コード例 #1
0
 public static void ServerStop()
 {
     try
     {
         if (sr_clientList.Count == 0)
         {
             if (ServerNetworkEngineServerStoppedEvent != null)
             {
                 ServerNetworkEngineServerStoppedEvent.Invoke();
             }
             Status = false;
             s_serverSocket.Close();
             return;
         }
         Status = false;
         if (ServerNetworkEngineServerStopBeganEvent != null)
         {
             ServerNetworkEngineServerStopBeganEvent.Invoke(sr_clientList.Count);
         }
         MessageStructure msgToSend = new MessageStructure
         {
             Command = Command.Disconnect
         };
         byte[] msgToSendByte = msgToSend.ToByte();
         Task.Factory.StartNew(() =>
         {
             foreach (Client client in sr_clientList)
             {
                 // Added only to slow down the progress bar advance for demonstration purposes
                 Thread.Sleep(150);
                 client.Socket.BeginSend(msgToSendByte, 0, msgToSendByte.Length, SocketFlags.None, OnSend, client.Socket);
             }
         });
         s_serverSocket.Close();
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message + @" -> btnStopSrv_Click", @"Server", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
コード例 #2
0
        private static void OnReceive(IAsyncResult ar)
        {
            //if (!s_serverEngineStatus) {
            //    return;
            //}
            try
            {
                // Casting the AsyncState to a socket class
                Socket receivedClientSocket = (Socket)ar.AsyncState;
                receivedClientSocket.EndReceive(ar);
                // Translating the array of received bytes to  an intelligent class MessageStructure
                MessageStructure msgReceived = new MessageStructure(sr_byteMessage);
                // Constract the initial details of new object MessageStructure which will be sent out
                MessageStructure msgToSend = new MessageStructure
                {
                    UserName   = msgReceived.UserName,
                    Command    = msgReceived.Command,
                    ClientName = msgReceived.ClientName,
                    Color      = msgReceived.Color
                };
                // Create a new byte[] class which will filled in the following case switch statment
                byte[] messageBytes;
                switch (msgReceived.Command)
                {
                case Command.Register:
                    msgToSend.Message = ServerDataEngine.Register(msgReceived.UserName, "Haven't logged in yet", "null", "Offline");
                    messageBytes      = msgToSend.ToByte();
                    receivedClientSocket.Send(messageBytes, 0, messageBytes.Length, SocketFlags.None);
                    return;

                case Command.AttemptLogin:
                    if (sr_clientList.Any(client => client.Name == msgReceived.ClientName))
                    {
                        msgToSend.Message = "This Name already in use";
                        messageBytes      = msgToSend.ToByte();
                        receivedClientSocket.Send(messageBytes, 0, messageBytes.Length, SocketFlags.None);
                        receivedClientSocket.Close();
                        return;
                    }
                    if (ServerDataEngine.CheckIfRegistered(msgReceived.UserName) == 0)
                    {
                        msgToSend.Message = "No user found which matches this User name";
                        messageBytes      = msgToSend.ToByte();
                        receivedClientSocket.Send(messageBytes, 0, messageBytes.Length, SocketFlags.None);
                        receivedClientSocket.Close();
                        return;
                    }
                    if (ServerDataEngine.CheckStatus(msgReceived.UserName) == "Online")
                    {
                        msgToSend.Message = "This User Name already logged in";
                        messageBytes      = msgToSend.ToByte();
                        receivedClientSocket.Send(messageBytes, 0, messageBytes.Length, SocketFlags.None);
                        receivedClientSocket.Close();
                        return;
                    }

                    msgToSend.Command   = Command.Login;
                    msgReceived.Command = Command.Login;
                    //messageBytes = msgToSend.ToByte();
                    //receivedClientSocket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, receivedClientSocket);
                    goto case Command.Login;

                case Command.Login:
                    // When the Login Command is received the ServerNetworkEngine will
                    // add that established connection (Socket) along
                    // with the provoided information to distinguish it (Name) to sr_clientList
                    // as a Client and sent the command Login to ohter clients to handle
                    // it on their end excluding the sending client
                    // and set the status of the new logged in client to online
                    Client newClient = new Client
                    {
                        UserName   = msgReceived.UserName,
                        Name       = msgReceived.ClientName,
                        Socket     = receivedClientSocket,
                        Color      = ColorTranslator.FromHtml(msgReceived.Color),
                        IpEndPoint = receivedClientSocket.RemoteEndPoint as IPEndPoint
                    };
                    // Adding the current handled established connection(client) to the connected _clientList
                    sr_clientList.Add(newClient);
                    // Setting the message to broadcast to all other clients
                    msgToSend.Message = "<<< " + newClient.Name + " has joined the room >>>";
                    ServerDataEngine.UpdateStatus(msgReceived.UserName, msgReceived.ClientName, "Online");
                    ServerDataEngine.UpdateDate(msgReceived.UserName, Time.NowTimeDate());
                    if (ServerNetworkEngineEngineClientToAddEvent != null)
                    {
                        ServerNetworkEngineEngineClientToAddEvent.Invoke(newClient.Name, newClient.IpEndPoint);
                    }
                    break;

                case Command.Logout:
                    // When the Logout Command is received the ServerNetworkEngine will
                    // remove the the client from _clientList a long with all of
                    // it's information, socket/clientName etc..
                    // server engine will also stop listening to the removed socket
                    // and broadcast the message to all clients excluding the removed client
                    receivedClientSocket.Shutdown(SocketShutdown.Both);
                    receivedClientSocket.BeginDisconnect(true, (OnDisonnect), receivedClientSocket);
                    // Setting the message to broadcast to all other clients
                    msgToSend.Message = "<<< " + msgReceived.ClientName + " has just left the chat >>>";
                    // Removing client (established connection) _clientList
                    foreach (Client client in sr_clientList.Where(client => client.Socket == receivedClientSocket))
                    {
                        sr_clientList.Remove(client);
                        ServerDataEngine.UpdateStatus(client.UserName, msgReceived.ClientName, "Offline");
                        break;
                    }
                    if (ServerNetworkEngineClientToRemoveEvent != null)
                    {
                        ServerNetworkEngineClientToRemoveEvent.Invoke(msgReceived.ClientName);
                    }
                    break;

                case Command.Disconnect:
                    receivedClientSocket.BeginDisconnect(true, (OnDisonnect), receivedClientSocket);
                    if (ServerNetworkEngineServerStopTickEvent != null)
                    {
                        ServerNetworkEngineServerStopTickEvent.Invoke(msgReceived.ClientName);
                    }
                    ServerDataEngine.UpdateStatus(msgReceived.UserName, msgReceived.ClientName, "Offline");
                    ++s_disconnectCout;
                    if (sr_clientList.Count == s_disconnectCout)
                    {
                        if (ServerNetworkEngineServerStoppedEvent != null)
                        {
                            ServerNetworkEngineServerStoppedEvent.Invoke();
                        }
                        ServerDataEngine.ResetStatus();
                    }
                    break;

                case Command.List:
                    // when the List command received serverEngine will send the names of all the
                    // clients(established coneections) back to the requesting (client) (established connection)
                    msgToSend.Command = Command.List;
                    Client lastItem = sr_clientList[sr_clientList.Count - 1];
                    //msgToSend.ClientName = lastItem.Name;
                    foreach (Client client in sr_clientList)
                    {
                        //To keep things simple we use a marker to separate the user names
                        msgToSend.Message += client.Name + ",";
                    }
                    // Convert msgToSend to a bytearray representative, this is needed in order to send(broadcat) the message over the TCP protocol
                    messageBytes = msgToSend.ToByte();
                    // Send(broadcast) the name of the estalished connections(cleints) in the chat
                    receivedClientSocket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, receivedClientSocket);
                    break;

                case Command.Message:
                    // Set the message which will be broadcasted to all the connected clients
                    ServerDataEngine.AddMessage(msgReceived.UserName, msgReceived.Message, Time.NowTimeDate(), "false", "null");
                    msgToSend.Message = msgReceived.Message;
                    if (ServerNetworkEngineSendPublicMessageEvent != null)
                    {
                        ServerNetworkEngineSendPublicMessageEvent.Invoke(msgToSend.ClientName, ColorTranslator.FromHtml(msgReceived.Color), msgToSend.Message);
                    }
                    break;

                case Command.NameChange:
                    foreach (Client client in sr_clientList.Where(client => client.Name == msgReceived.ClientName))
                    {
                        client.Name = msgReceived.Message;
                        break;
                    }
                    msgToSend.Message = msgReceived.Message;
                    if (ServerNetworkEngineClientNameChangedEvent != null)
                    {
                        ServerNetworkEngineClientNameChangedEvent.Invoke(msgReceived.ClientName, msgReceived.Message);
                    }
                    ServerDataEngine.UpdateLoggedLastLogged(msgReceived.ClientName, msgReceived.Message);
                    goto case Command.ColorChanged;

                case Command.ColorChanged:
                    Color newColor = ColorTranslator.FromHtml(msgToSend.Color);
                    foreach (Client client in sr_clientList.Where(client => client.Name == msgReceived.ClientName))
                    {
                        client.Color = newColor;
                        break;
                    }
                    msgToSend.Message = msgReceived.Message;
                    if (ServerNetworkEngineClientColorChangedEvent != null)
                    {
                        ServerNetworkEngineClientColorChangedEvent.Invoke(msgReceived.ClientName, newColor);
                    }
                    break;

                case Command.PrivateStart:
                    foreach (Client client in sr_clientList.Where(client => client.Name == msgReceived.Private))
                    {
                        msgToSend.Private = msgReceived.Private;
                        messageBytes      = msgToSend.ToByte();
                        client.Socket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, client.Socket);
                        if (ServerNetworkEnginePrivateChatStartedEvent != null)
                        {
                            ServerNetworkEnginePrivateChatStartedEvent.Invoke(msgReceived.ClientName, msgReceived.Private);
                        }
                        break;
                    }
                    break;

                case Command.PrivateMessage:
                    foreach (Client client in sr_clientList.Where(clientLinq => clientLinq.Name == msgReceived.Private))
                    {
                        msgToSend.Private = msgReceived.Private;
                        msgToSend.Message = msgReceived.Message;
                        messageBytes      = msgToSend.ToByte();
                        client.Socket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, client.Socket);
                        receivedClientSocket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, receivedClientSocket);
                        if (ServerNetworkEnginePrivateChatMessageEvent != null)
                        {
                            ServerNetworkEnginePrivateChatMessageEvent.Invoke(msgReceived.ClientName, msgReceived.Private, msgReceived.Message);
                        }
                        ServerDataEngine.AddMessage(msgReceived.UserName, msgReceived.Message, Time.NowTimeDate(), client.UserName, "null");
                        break;
                    }
                    break;

                case Command.PrivateStopped:
                    foreach (Client client in sr_clientList.Where(clientLinq => clientLinq.Name == msgReceived.Private))
                    {
                        msgToSend.Private = msgReceived.Private;
                        messageBytes      = msgToSend.ToByte();
                        client.Socket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, client.Socket);
                        receivedClientSocket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, receivedClientSocket);
                    }
                    if (ServerNetworkEnginePrivateChatStoppedEvent != null)
                    {
                        ServerNetworkEnginePrivateChatStoppedEvent.Invoke(msgReceived.ClientName, msgReceived.Private);
                    }
                    break;

                case Command.ImageMessage:
                    MemoryStream s_ms  = new MemoryStream(msgReceived.ImgByte);
                    Image        s_img = Image.FromStream(s_ms);
                    if (!Directory.Exists(@"Images\" + msgReceived.UserName))
                    {
                        Directory.CreateDirectory(@"Images\" + msgReceived.UserName);
                    }
                    if (msgReceived.Private != null)
                    {
                        if (ServerNetworkEngineImageMessageEvent != null)
                        {
                            ServerNetworkEngineImageMessageEvent.Invoke(s_img, msgReceived.ClientName, msgReceived.Private);
                        }
                        Task.Factory.StartNew(() =>
                        {
                            foreach (Client client in sr_clientList.Where(clientLinq => clientLinq.Name == msgReceived.Private))
                            {
                                msgToSend.Private = msgReceived.Private;
                                msgToSend.ImgByte = msgReceived.ImgByte;
                                messageBytes      = msgToSend.ToByte();
                                client.Socket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, client.Socket);
                                receivedClientSocket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, receivedClientSocket);
                                ServerDataEngine.AddMessage(msgReceived.UserName, "null", Time.NowTimeDate(), client.UserName, @"Images\" + msgReceived.UserName + @"\" + Time.SaveTimeDate() + @"-" + client.UserName);
                                //s_img.Save(@"Images\" + msgReceived.Private + @"\" + Time.SaveTimeDate() + client.UserName + @".png");
                                s_img.Save(@"Images\" + msgReceived.UserName + @"\" + Time.SaveTimeDate() + @".png");
                                break;
                            }
                        });
                        break;
                    }
                    if (ServerNetworkEngineImageMessageEvent != null)
                    {
                        ServerNetworkEngineImageMessageEvent.Invoke(s_img, msgReceived.ClientName, msgReceived.Private);
                    }
                    msgToSend.ImgByte = msgReceived.ImgByte;
                    messageBytes      = msgToSend.ToByte();
                    Task.Factory.StartNew(() =>
                    {
                        foreach (Client client in sr_clientList)
                        {
                            client.Socket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, client.Socket);
                            ServerDataEngine.AddMessage(msgReceived.UserName, "null", Time.NowTimeDate(), "false", @"Images\" + msgReceived.UserName + @"\" + Time.SaveTimeDate());
                            s_img.Save(@"Images\" + msgReceived.UserName + @"\" + Time.SaveTimeDate() + @".png");
                        }
                    });
                    break;
                }

                // Send(broadcast) the message to clients (established connections)
                Task.Factory.StartNew(() =>
                {
                    if (msgToSend.Command != Command.List && msgToSend.Command != Command.PrivateStart && msgToSend.Command != Command.PrivateMessage && msgToSend.Command != Command.PrivateStopped && msgToSend.Command != Command.Disconnect && msgToSend.Command != Command.ImageMessage)
                    {
                        messageBytes = msgToSend.ToByte();
                        foreach (Client client in sr_clientList)
                        {
                            //if (client.Socket != receivedClientSocket || msgToSend.Command != Command.Login) {
                            client.Socket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, OnSend, client.Socket);
                            //}
                        }
                    }
                });
                // Continue listneing to receivedClientSocket established connection(client)
                if (msgReceived.Command != Command.Logout && msgReceived.Command != Command.Disconnect && msgReceived.Command != Command.AttemptLogin && msgReceived.Command != Command.Register)
                {
                    receivedClientSocket.BeginReceive(sr_byteMessage, 0, sr_byteMessage.Length, SocketFlags.None, OnReceive, receivedClientSocket);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + @" -> OnReceive", @"Server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }