Асинхронный сервер не отвечает - C#

Узнай цену своей работы

Формулировка задачи:

Добра. Написал асинхронных сервер сервер и клиент для чата. Порядок работы примерно таков: Клиент подключается к серверу Сервер получает запрос от клиента и отвечает ему.(если команда была непонятна отвечает "unknown command") В то же время, на сервере хранится лист объектов класса User.
 class User
        {
            public string ID;
            public int room;
            public Socket sock;
            public User(string ID, int room, Socket sock)
            {
                this.ID = ID;
                this.sock = sock;
                this.room = room;
            }
        }
И когда приходит команда,например, написать сообщение в комнату, он определяет, в какой комнате находится сам юзер, достаёт всех юзеров с такой же комнаты и на их сокеты отправляет сообщение. Всё просто. Так же работает и юзер. Асинхронно отправляет команду, послу чего асинхронно ждёт ответ. Ок. У меня на ПК всё работает как часы, но как только я решил потестить на другом ПК - появилась неочевидная проблема. Сначала сервер отвечает клиенту нормально, но потом, не понятно из-за чего, сервер перестаёт отвечать. При чём клиент говорит, что сообщение отправил. Я приложил скриншот с исключением. Так мы с другом перекинулись парой сообщений, а потом ему перестал отвечать сервер. Подскажите, что в таких случаях делать? Спасибо. P.S. На всякий случай прикладываю код сервера и клиента. Сервер:
 public class StateObject
    {
        // Client  socket.
        public Socket workSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder sb = new StringBuilder();
    }
    public class AsynchronousSocketListener
    {
        // Thread signal.
        public static ManualResetEvent allDone = new ManualResetEvent(false);
        public AsynchronousSocketListener()
        {
        }
 
        public static void StartListening(int PORT)
        {
            // Data buffer for incoming data.
            byte[] bytes = new Byte[1024];
 
            // Establish the local endpoint for the socket.
            // The DNS name of the computer
            // running the listener is "host.contoso.com".
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.103"), PORT);
 
            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
            // Bind the socket to the local endpoint and listen for incoming connections.
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);
 
                while (true)
                {
                    // Set the event to nonsignaled state.
                    allDone.Reset();
 
                    // Start an asynchronous socket to listen for connections.
                    Console.WriteLine("Waiting for a connection...");
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
 
                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                }
 
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
 
            Console.WriteLine("\nPress ENTER to continue...");
            Console.Read();
 
        }
 
        public static void AcceptCallback(IAsyncResult ar)
        {
            // Signal the main thread to continue.
            allDone.Set();
 
            // Get the socket that handles the client request.
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);
 
            // Create the state object.
            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }
 
        public static void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;
 
            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            try
            {

                // Read data from the client socket. 
                int bytesRead = handler.EndReceive(ar);
 
                if (bytesRead > 0)
                {
                    // There  might be more data, so store the data received so far.
                    state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));
 
                    // Check for end-of-file tag. If it is not there, read 
                    // more data.
                    content = state.sb.ToString();
                    if (content.IndexOf("<EOF>") > -1)
                    {
                        // All the data has been read from the client. Display it on the console.
                        Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
                        // Echo the data back to the client.
                        //Send(handler, content);
                        classUsersWorker.CommandReaction(content, handler);
 
                        /*StateObject state1 = new StateObject();
                        state1.workSocket = handler;
                        handler.BeginReceive(state1.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state1);*/
                    }
                    else
                    {
                        // Not all data received. Get more.
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                    }
                }
            }
            catch (Exception e)
            {
                try
                {
                    Console.WriteLine(e.Message);
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                }
                catch { }
            }
        }
 
        public static void Send(Socket handler, String data)
        {
            // Convert the string data to byte data using UTF8 encoding.
            byte[] byteData = Encoding.UTF8.GetBytes(data + "<EOF>");
 
            // Begin sending the data to the remote device.
            handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
        }
 
        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket handler = (Socket)ar.AsyncState;
 
                // Complete sending the data to the remote device.
                int bytesSent = handler.EndSend(ar);
                Console.WriteLine("Sent {0} bytes to client.", bytesSent);
 
                //handler.Shutdown(SocketShutdown.Both);
                //handler.Close();
 
                // Create the state object.
                StateObject state = new StateObject();
                state.workSocket = handler;
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
 
    }
    public class classUsersWorker
    {
        class User
        {
            public string ID;
            public int room;
            public Socket sock;
            public User(string ID, int room, Socket sock)
            {
                this.ID = ID;
                this.sock = sock;
                this.room = room;
            }
        }
        private static List<User> Users = new List<User>();
 
        private static string UserIDGenerator()
        {
            int ID = new Random().Next(10000, 99999);
            foreach (User item in Users)
            {
                if (item.ID == ID.ToString())
                {
                    UserIDGenerator();
                    break;
                }
            }
            return ID.ToString();
        }
        private static int RoomGenerator()
        {
            int room = new Random().Next(100, 999);
            foreach (User item in Users)
            {
                if (item.room == room)
                {
                    UserIDGenerator();
                    break;
                }
            }
            return room;
        }
        private static User[] FindUsersInRoom(int room)
        {
            List<User> u = new List<User>();
            foreach (User item in Users)
                if (item.room == room)
                    u.Add(item);
            return u.ToArray();
 
        }
        private static bool IsRoom(int room)
        {
            foreach (User item in Users)
                if (item.room == room) return true;
            return false;
        }
        private static bool RoomCreate(string command, Socket sock)
        {
            try
            {
                int room = RoomGenerator();
                User u = new User(UserIDGenerator(), room, sock);
                Users.Add(u);
                AsynchronousSocketListener.Send(sock, "<room>" + room);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        private static bool RoomConnect(string command, Socket sock)
        {
            string res = command.Replace("<room_connect>", "").Replace("<EOF>", "");
            try
            {
 
                int room = Int32.Parse(res);
                if (IsRoom(room))
                {
                    User u = new User(UserIDGenerator(), room, sock);
                    Users.Add(u);
                    AsynchronousSocketListener.Send(sock, "<room>" + room);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }
        private static bool WriteToRoom(string command, Socket sock)
        {
            string[] StringSeparators = new string[] { "<write>", "<to>", "<EOF>" };
            string[] result = command.Split(StringSeparators, StringSplitOptions.None);
            try
            {
                string msg = result[1];
                int room = Int32.Parse(result[2]);
                User[] Roomers = FindUsersInRoom(room);
                bool access = false;
                foreach (User item in Roomers)
                    if (item.sock == sock) access = true;
                if (access == true)
                {
                    foreach (User item in Roomers)
                        AsynchronousSocketListener.Send(item.sock, msg);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
 
        }
 
        public static bool CommandReaction(string command, Socket sock)
        {
            if (command.Contains("<room_create>"))
                if (RoomCreate(command, sock)) return true;
            if (command.Contains("<room_connect>"))
                if (RoomConnect(command, sock)) return true;
            if (command.Contains("<write>"))
                if (WriteToRoom(command, sock)) return true;
            AsynchronousSocketListener.Send(sock, "Unknown command<EOF>");
            return false;
        }
    }
    class Program
    {
        public static int Main(String[] args)
        {
            AsynchronousSocketListener.StartListening(1100);
            return 0;
        }
    }

Решение задачи: «Асинхронный сервер не отвечает»

textual
Листинг программы
    class Program
    {
        public static void Send(Socket handler, String data)
        {
            // Convert the string data to byte data using UTF8 encoding.
            byte[] byteData = Encoding.UTF8.GetBytes(data + "<EOF>");
 
            // Begin sending the data to the remote device.
            handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
        }
 
        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket handler = (Socket)ar.AsyncState;
 
                // Complete sending the data to the remote device.
                int bytesSent = handler.EndSend(ar);
                Console.WriteLine("Sent {0} bytes", bytesSent);
 
                //handler.Shutdown(SocketShutdown.Both);
                //handler.Close();
 
                // Create the state object.
                StateObject state = new StateObject();
                state.workSocket = handler;
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Console.ReadLine();
            }
        }
 
        public static void StartClient()
        {
            // Establish the remote endpoint for the socket.
            // This example uses port 11000 on the local computer.
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("92.249.117.132"), 1100);
 
            // Create a TCP/IP  socket.
            Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            while (true)
            {
 
                // Data buffer for incoming data.
                byte[] bytes = new byte[1024];
 
                try
                {
                    if (!sender.Connected)
                    {
                        sender.Connect(remoteEP);
                        Console.WriteLine("Socket connected to {0}", sender.RemoteEndPoint.ToString());
                    }
                    string command = Console.ReadLine();
 
                    // Send the data through the socket.
                    Send(sender, command);
 
                    // Release the socket.
                    // sender.Shutdown(SocketShutdown.Both);
                    // sender.Close();
 
                }
                catch (ArgumentNullException ane)
                {
                    Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
                }
                catch (SocketException se)
                {
                    Console.WriteLine("SocketException : {0}", se.ToString());
                }
                catch (Exception e)
                {
                    Console.WriteLine("Unexpected exception : {0}", e.ToString());
                }
 
            }
        }
        public static void ReadCallback(IAsyncResult ar)
        {
 
            String content = String.Empty;
 
            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            try
            {
                // Read data from the client socket. 
                int bytesRead = handler.EndReceive(ar);
 
                if (bytesRead > 0)
                {
                    // There  might be more data, so store the data received so far.
                    state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));
 
                    // Check for end-of-file tag. If it is not there, read 
                    // more data.
                    content = state.sb.ToString();
                    if (content.IndexOf("<EOF>") > -1)
                    {
                        // All the data has been read from the client. Display it on the console.
                        Console.WriteLine(content.Replace("<EOF>", ""));
 
 
                        StateObject state1 = new StateObject();
                        state1.workSocket = handler;
                        handler.BeginReceive(state1.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state1);
                    }
                    else
                    {
                        // Not all data received. Get more.
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
            }
        }
 
        static void Main(string[] args)
        {
            StartClient();
        }
    }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 4.2 из 5
Похожие ответы