示例#1
0
        private void recvMessage(object s)
        {
            ConnectedClient client = ConnectedClients[(int)s];

            try
            {
                byte[] buffer    = new byte[(int)Msg.Size];
                int    recvbytes = 0;
                recvbytes = client.tcpClient.Client.Receive(buffer, (int)Msg.Size, SocketFlags.None);
                if (recvbytes > 0)
                {
                    #region RecvClientSettings
                    if (BitConverter.ToUInt32(buffer, (int)Msg.ID) == (int)MsgType.ClientSettings)
                    {
                        ClientSettings CSettings;
                        CSettings = (ClientSettings)Utils.ByteArrayToObject(buffer);
                        for (int i = 0; i < ConnectedClients.Count(); i++)
                        {
                            if (ConnectedClients[i].tcpClient.Client == client.tcpClient.Client)
                            {
                                ConnectedClients[i].Name = CSettings.Name;
                            }
                        }
                        client.Name  = CSettings.Name;
                        client.Group = CSettings.Groups;
                        string[] tmpGroups = CSettings.Groups.Split(';');
                        foreach (string group in tmpGroups)
                        {
                            if (group != "")
                            {
                                bool InGroupList = false;
                                for (int i = 0; i < chatGroup.Count(); i++)
                                {
                                    if (group == chatGroup[i].GroupName)
                                    {
                                        InGroupList = true; // group is already in chatrgouplist,
                                                            // now we check if out player is already in that group
                                        bool PlayerAlreadyInGroup = false;
                                        for (int j = 0; j < chatGroup[i].Members.Count(); j++)
                                        {
                                            if (chatGroup[i].Members[j] == CSettings.Name)
                                            {
                                                PlayerAlreadyInGroup = true;
                                            }
                                        }
                                        if (!PlayerAlreadyInGroup)
                                        {
                                            chatGroup[i].Members.Add(CSettings.Name);
                                            Console.WriteLine(CSettings.Name + " added to group : " + chatGroup[i].GroupName);
                                        }
                                    }
                                }
                                if (!InGroupList)
                                {
                                    ChatGroup cGroup = new ChatGroup();
                                    cGroup.GroupName = group;
                                    cGroup.Members.Add(CSettings.Name);
                                    chatGroup.Add(cGroup);
                                    Console.WriteLine("Group " + group + " Added to List with And Added Member : " + CSettings.Name);
                                }
                            }
                        }

                        UpdateClientList();
                    }
                    #endregion
                    #region RecvTextMessage
                    if (BitConverter.ToInt32(buffer, (int)Msg.ID) == (int)MsgType.TextMessage)
                    {
                        TextMessage TM = new TextMessage();
                        TM = (TextMessage)Utils.ByteArrayToObject(buffer);
                        PassMessage(TM, buffer);
                    }
                    #endregion
                    #region FileRecv/Send
                    if (BitConverter.ToInt32(buffer, (int)Msg.ID) == (int)MsgType.PrepareSendFile)
                    {
                        PrepareFileSend PFS = new PrepareFileSend();
                        PFS     = (PrepareFileSend)Utils.ByteArrayToObject(buffer);
                        PFS.ACK = 1;
                        Utils.ObjectToByteArray(PFS).CopyTo(buffer, 0);
                        BitConverter.GetBytes((int)MsgType.RequestFile).CopyTo(buffer, (int)Msg.ID);
                        client.tcpClient.Client.Send(buffer, (int)Msg.Size, SocketFlags.None); // Send Ready to recvfile.

                        buffer = new byte[PFS.filesize];
                        int chunk = (int)Msg.FileDataChunk;
                        recvbytes = 0;
                        int percent = 0;
                        while (recvbytes != buffer.Length)
                        {
                            recvbytes += client.tcpClient.Client.Receive(buffer, recvbytes, chunk, SocketFlags.None);
                            if (chunk > buffer.Length - recvbytes)
                            {
                                chunk = buffer.Length - recvbytes;
                            }
                            percent = (int)((100.0 / (float)buffer.Length) * (float)recvbytes);

                            SendFileRecvUpdate(client, percent);
                        }
                        SendFileRecvUpdate(client, 1000);

                        ServerFile SF = new ServerFile();
                        SF.Name       = PFS.FileName;
                        SF.BinaryFile = new byte[PFS.filesize];
                        SF.size       = PFS.filesize;
                        buffer.CopyTo(SF.BinaryFile, 0);
                        BinaryFiles.Add(SF);
                        // File added to BinaryList;
                        // now we need to notify clients that there is a file for them.
                        TextMessage TM = new TextMessage();
                        TM.To      = PFS.to;
                        TM.From    = PFS.from;
                        TM.ID      = ChatBufferMessageType.Link;
                        TM.Message = PFS.FileName;
                        buffer     = new byte[(int)Msg.Size];
                        BitConverter.GetBytes((int)MsgType.TextMessage).CopyTo(buffer, (int)Msg.ID);
                        Utils.ObjectToByteArray(TM).CopyTo(buffer, 0);
                        PassMessage(TM, buffer);
                    }

                    #endregion
                    #region File Request Awsering
                    if (BitConverter.ToInt32(buffer, (int)Msg.ID) == (int)MsgType.RequestFile)
                    {
                        RequestFile RF = new RequestFile();
                        RF = (RequestFile)Utils.ByteArrayToObject(buffer);
                        for (int i = 0; i < BinaryFiles.Count(); i++)
                        {
                            if (BinaryFiles[i].Name.Contains(RF.Name))
                            {
                                PrepareFileSend PFS = new PrepareFileSend();
                                PFS.filesize = BinaryFiles[i].size;
                                PFS.FileName = BinaryFiles[i].Name;
                                PFS.ACK      = 0;
                                BitConverter.GetBytes((int)MsgType.PrepareSendFile).CopyTo(buffer, (int)Msg.ID);
                                Utils.ObjectToByteArray(PFS).CopyTo(buffer, 0);
                                client.tcpClient.Client.Send(buffer, (int)Msg.Size, SocketFlags.None);

                                recvbytes = 0;
                                recvbytes = client.tcpClient.Client.Receive(buffer, (int)Msg.Size, SocketFlags.None);
                                PFS       = (PrepareFileSend)Utils.ByteArrayToObject(buffer);
                                if (PFS.ACK == 1)
                                {
                                    client.tcpClient.Client.Send(BinaryFiles[i].BinaryFile, (int)BinaryFiles[i].size, SocketFlags.None);
                                }
                            }
                        }
                    }
                    #endregion
                }
                if (recvbytes == 0)
                {
                    for (int i = 0; i < ConnectedClients.Count(); i++)
                    {
                        if (ConnectedClients[i].tcpClient.Client == client.tcpClient.Client)
                        {
                            ConnectedClients.RemoveAt(i);
                            break;
                        }
                    }
                    Console.WriteLine("Client Disconnected");
                }

                for (int i = 0; i < ConnectedClients.Count(); i++)
                {
                    if (client.Name == ConnectedClients[i].Name)
                    {
                        ConnectedClients[i].IsRunning = false;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
示例#2
0
        //every client runs on its own thread.
        //File send and receives also runs on its own thread. this is to keep GUI responsive.
        private void recvMessage(object s)
        {
            ConnectedClient client       = (ConnectedClient)s;
            bool            bRecvMessage = true;

            while (bRecvMessage)
            {
                try
                {
                    nBuffer buffer = new nBuffer();
                    int     ReadBytes;
                    if ((ReadBytes = buffer.ReceiveCryptoBuffer(client.socket, client.CC.Salt)) > 0)
                    {
                        #region RecvClientSettings
                        if (buffer.GetID() == MsgType.ClientSettings)
                        {
                            Console.WriteLine(client.socket.RemoteEndPoint.ToString() + ": Received Client settings");
                            ClientSettings CSettings;

                            CSettings    = buffer.GetObject <ClientSettings>();
                            CSettings.Ip = client.CC.Ip;

                            bool InGroupList = false;

                            for (int i = 0; i < ConnectedClients.Count(); i++)
                            {
                                if (ConnectedClients[i].CC.Ip == client.CC.Ip)
                                {
                                    Console.WriteLine(ConnectedClients[i].Name + " Renamed to: " + CSettings.Name);
                                    ConnectedClients[i].Name = CSettings.Name;
                                }
                            }
                            client.Groups = CSettings.Groups;
                            string[] tmpGroups = CSettings.Groups.Split(';');
                            foreach (string group in tmpGroups)
                            {
                                if (group != "")
                                {
                                    InGroupList = false;
                                    for (int i = 0; i < ChatGroupsContainer.Instance.Count; i++)
                                    {
                                        if (group == ChatGroupsContainer.Instance.at(i).GroupName)
                                        {
                                            InGroupList = true; // group is already in chatrgrouplist,
                                        }
                                    }
                                    if (!InGroupList)
                                    {
                                        ChatGroup cGroup = new ChatGroup();
                                        cGroup.GroupName = group;
                                        ChatGroupsContainer.Instance.Add(cGroup);
                                        AddGroupToDataGridview(cGroup);
                                        Console.WriteLine("Group " + group + " Added to List");
                                    }
                                    // check if user is in group, else add it, and check if name updated;
                                    for (int i = 0; i < ChatGroupsContainer.Instance.Count; i++)
                                    {
                                        bool UserInList = false;
                                        if (ChatGroupsContainer.Instance.at(i).GroupName == group)
                                        {
                                            for (int j = 0; j < ChatGroupsContainer.Instance.at(i).Members.Count; j++)
                                            {
                                                if (ChatGroupsContainer.Instance.at(i).Members[j].Ip == CSettings.Ip) // Member is in list
                                                {
                                                    UserInList = true;
                                                    ChatGroupsContainer.Instance.at(i).Members[j].Name = CSettings.Name; // update name.
                                                }
                                            }
                                            if (!UserInList)
                                            {
                                                ChatGroupsContainer.Instance.at(i).Members.Add(CSettings);
                                                Console.WriteLine(CSettings.Name + " Added to: " + ChatGroupsContainer.Instance.at(i).GroupName);
                                            }
                                        }
                                    }
                                }
                            }

                            // check all groups if it has the user, if it does, check if the user has specified the group, else delete it from that group
                            for (int j = 0; j < ChatGroupsContainer.Instance.Count; j++)
                            {
                                bool UserInGroup        = false;
                                bool UserSpecifiedGroup = false;
                                int  IndexOfUser        = -1;
                                for (int i = 0; i < ChatGroupsContainer.Instance.WholeList[j].Members.Count; i++)
                                {
                                    if (ChatGroupsContainer.Instance.at(j).Members[i].Ip == CSettings.Ip) // client is in the group
                                    {
                                        UserInGroup = true;
                                        foreach (string Cgroups in tmpGroups) // check if groupname is also specified by teh client;
                                        {
                                            if (Cgroups == ChatGroupsContainer.Instance.at(j).GroupName)
                                            {
                                                UserSpecifiedGroup = true;
                                            }
                                        }
                                        if (!UserSpecifiedGroup)
                                        {
                                            IndexOfUser = i;
                                        }
                                    }
                                }
                                if (UserInGroup && !UserSpecifiedGroup) // user is in chatgroup but not specified in tmpgroups.
                                {
                                    ChatGroupsContainer.Instance.at(j).Members.RemoveAt(IndexOfUser);
                                }
                            }
                            UpdateClientList();
                        }
                        #endregion

                        #region RecvTextMessage

                        if (buffer.GetID() == MsgType.TextMessage)
                        {
                            Console.WriteLine(client.socket.RemoteEndPoint.ToString() + ": Received TextMessage");
                            TextMessage TM = buffer.GetObject <TextMessage>();
                            PassMessage(TM);
                            if (LogChatMessages.Checked)
                            {
                                MessageLogger.LOG(TM, ChatGroupsContainer.Instance.WholeList);
                            }
                        }
                        #endregion

                        #region FileRecv/Send
                        if (buffer.GetID() == MsgType.SendFile) // Server Receives file
                        {
                            PrepareFileSend PFS = buffer.GetObject <PrepareFileSend>();
                            Console.WriteLine(client.socket.RemoteEndPoint.ToString() + ": Send File -> " + PFS.FileName + PFS.Ext);
                            buffer.innerbuffer.Clear();
                            buffer.ReceiveCryptoFileBuffer(client.socket, client.CC.Salt);
                            ServerFile SF = buffer.GetObject <ServerFile>(0);
                            // Encrypt current password into file;
                            byte[] Passwordbytes = Crypt.Base64Encode(BinaryFilesPassword);
                            byte[] binaryfile    = new byte[Passwordbytes.Length + SF.BinaryFile.Length];
                            Buffer.BlockCopy(Passwordbytes, 0, binaryfile, 0, Passwordbytes.Length);
                            Buffer.BlockCopy(SF.BinaryFile, 0, binaryfile, Passwordbytes.Length, SF.BinaryFile.Length); // copy binary file;

                            binaryfile = Crypt.Encrypt(binaryfile, BinaryFilesKey, BinaryFilesPassword);                // encrypt file and store it.

                            string     Path = Utils.AssemblyDirectory + "\\" + PFS.FileName + PFS.Ext + ".scbd";
                            FileStream fs   = null;
                            if (File.Exists(Path))
                            {
                                fs = new FileStream(Path, FileMode.Truncate, FileAccess.ReadWrite); // overwrite file
                            }
                            else
                            {
                                fs = new FileStream(Path, FileMode.OpenOrCreate, FileAccess.ReadWrite); // create new;
                            }
                            if (fs.CanWrite)
                            {
                                fs.Write(binaryfile, 0, binaryfile.Length);
                            }
                            fs.Close();
                            fs.Dispose();
                            SF.length  = binaryfile.Length;
                            SF.Ext     = PFS.Ext;
                            binaryfile = null;

                            // now we need to notify clients that there is a file for them.
                            TextMessage TM = new TextMessage();
                            TM.To      = PFS.to;
                            TM.From    = PFS.from;
                            TM.ID      = ChatBufferMessageType.Link;
                            TM.Message = PFS.FileName + PFS.Ext;
                            PassMessage(TM);

                            buffer.innerbuffer.Clear();
                            buffer.AddID(MsgType.FileSendComplete);
                            FileSendComplete FSC = new FileSendComplete();
                            FSC.complete = true;
                            buffer.AddObject(FSC);
                            buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                        }

                        #endregion

                        #region File Request Awsering
                        if (buffer.GetID() == MsgType.RequestFile) // Client requests file from server
                        {
                            bool        NoFile = true;
                            RequestFile RF     = buffer.GetObject <RequestFile>();
                            Console.WriteLine(client.socket.RemoteEndPoint.ToString() + ": Request File -> " + RF.Name);
                            buffer.innerbuffer.Clear();

                            byte[] binaryfile = new byte[] { };
                            string Path       = Utils.AssemblyDirectory + "\\" + RF.Name + ".scbd";
                            if (File.Exists(Path))
                            {
                                binaryfile = Crypt.Decrypt(File.ReadAllBytes(Path), BinaryFilesKey, BinaryFilesPassword);
                                byte[] passwordbytes          = Crypt.Base64Encode(BinaryFilesPassword); // get bytes of password
                                byte[] binarypasswordfromfile = new byte[passwordbytes.Length];          // allocate bytes
                                try
                                {
                                    // copy length of of current password from binrayfile on disk;
                                    Buffer.BlockCopy(binaryfile, 0, binarypasswordfromfile, 0, binarypasswordfromfile.Length);
                                    string DecodedBinaryPassword = Crypt.Base64Decode(binarypasswordfromfile); // decode password
                                    if (DecodedBinaryPassword == BinaryFilesPassword)                          // password from file is the same as current password;
                                    {
                                        Buffer.BlockCopy(binaryfile, passwordbytes.Length, binaryfile, 0, binaryfile.Length - passwordbytes.Length);
                                    }
                                    else // password was longer/smaller or same length but different chars.
                                    {
                                        Console.WriteLine("Encrypted password does not match current password, file could not be send to user : "******"Failed to Decrypt file from disk");
                                    Console.WriteLine(ex.Message + "/n/r " + ex.StackTrace);
                                }
                                NoFile = false;

                                PrepareFileSend PFS = new PrepareFileSend();
                                PFS.filesize = binaryfile.Length;
                                PFS.FileName = RF.Name;
                                PFS.ACK      = 0;
                                buffer.AddID(MsgType.SendFile);
                                buffer.AddObject(PFS);
                                buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                                buffer.innerbuffer.Clear();
                                buffer.CryptoSize = 0;

                                buffer.ReceiveCryptoBuffer(client.socket, client.CC.Salt);
                                if (buffer.GetID() == MsgType.SendOK)
                                {
                                    buffer.innerbuffer.Clear();
                                    ServerFile serverfile = new ServerFile();
                                    string[]   splitname  = RF.Name.Split('.');
                                    serverfile.Name       = splitname[0]; // name
                                    serverfile.Ext        = splitname[1]; // extension
                                    serverfile.BinaryFile = binaryfile;   // decrypt file to send it.
                                    binaryfile            = null;
                                    buffer.AddObject(serverfile);
                                    Console.WriteLine("Server : " + buffer.SendCryptoBuffer(client.socket, client.CC.Salt) + " bytess  of " + RF.Name + " send!");
                                    buffer.innerbuffer.Clear();
                                }
                            }
                            if (NoFile)
                            {
                                PrepareFileSend PFS = new PrepareFileSend();
                                PFS.filesize = -1;
                                PFS.FileName = RF.Name;
                                PFS.ACK      = 0;
                                buffer.AddID(MsgType.Nofile);
                                buffer.AddObject(PFS);
                                buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                                buffer.innerbuffer.Clear();
                                Thread.Sleep(10);
                            }
                        }
                        #endregion
                        #region Reguest Logo
                        if (buffer.GetID() == MsgType.RequestLogo)
                        {
                            if (Logo == null)
                            {
                                buffer.innerbuffer.Clear();
                                buffer.AddID(MsgType.NoLogo);
                                buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                            }
                            else
                            {
                                buffer.innerbuffer.Clear();
                                buffer.AddID(MsgType.Logo);

                                buffer.AddObject(Logo);
                                buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                            }
                        }
                        #endregion
                    }
                    else
                    {
                        for (int i = 0; i < ConnectedClients.Count(); i++)
                        {
                            if (ConnectedClients[i].socket == client.socket)
                            {
                                if (client.CC.Ip == ConnectedClients[i].CC.Ip && client.CC.sockettype != ConnectionType.Client) // or delete if FileSocket.
                                {
                                    ConnectedClients[i].socket.Shutdown(SocketShutdown.Both);
                                    ConnectedClients[i].socket.Close(1);
                                    ConnectedClients.RemoveAt(i);
                                    Console.WriteLine("Socket of Type {0} Disconnected!", client.CC.sockettype);
                                    bRecvMessage = false;
                                    return;
                                }

                                client.socket.Shutdown(SocketShutdown.Both);
                                client.socket.Close(1);
                                client.socket = null;
                                client.Online = false;
                                bRecvMessage  = false;

                                Console.WriteLine("Client {0} of Type {1} Disconnected!", client.CC.Ip, client.CC.sockettype);
                                UpdateClientList();
                                return;
                            }
                        }
                        //  if (ConnectedClients[index].CC.sockettype != ConnectionType.File) // only update clientlist if socket is not a filesocket.
                        //       UpdateClientList();
                    }
                }
                catch (Exception e)
                {
                    for (int i = 0; i < ConnectedClients.Count(); i++)
                    {
                        if (client.socket == ConnectedClients[i].socket)
                        {
                            Console.WriteLine(ConnectedClients[i].CC.Ip + "   " + e.Message + "\r\n Disconnected");
                            if (i < ConnectedClients.Count())
                            {
                                /*
                                 * ConnectedClients[i].Online = false;
                                 * ConnectedClients[i].socket = null;
                                 * ConnectedClients[i].IsRunning = false;
                                 */
                                client.socket.Shutdown(SocketShutdown.Both);
                                client.socket.Close(1);
                                client.socket = null;
                                client.Online = false;
                                bRecvMessage  = false;
                            }
                        }
                    }
                }
            }
        }