Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
Nowsoud
1 / 1 / 0
Регистрация: 01.01.2015
Сообщений: 90
#1

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

06.07.2015, 16:10. Просмотров 404. Ответов 5
Метки нет (Все метки)

Добра.
Написал асинхронных сервер сервер и клиент для чата.

Порядок работы примерно таков:
Клиент подключается к серверу
Сервер получает запрос от клиента и отвечает ему.(если команда была непонятна отвечает "unknown command")
В то же время, на сервере хранится лист объектов класса User.
C#
1
2
3
4
5
6
7
8
9
10
11
12
 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. На всякий случай прикладываю код сервера и клиента.

Сервер:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
 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;
        }
    }
0
Миниатюры
Асинхронный сервер не отвечает  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.07.2015, 16:10
Ответы с готовыми решениями:

Асинхронный сервер
всем привет. У меня есть асинхронный сервер, который получает данные следующим...

Асинхронный клиент-сервер
Здравствуйте. Вот уже 3 дня бьюсь над проблемой, решение которой не могу найти....

Асинхронный сервер на UDP-сокетах
Хай. Я как-то писал асинх. сервер с использованием TCP-протокола и все...

Асинхронный сокет сервер + SSL
Здравствуйте. Требуется написать асинхронный сервер + ssl. С этим(...

Как написать асинхронный UDP сервер?
Дайте пожалуйста код асинхронного UDP сервера и клиента для теста, необходимо...

5
Nowsoud
1 / 1 / 0
Регистрация: 01.01.2015
Сообщений: 90
06.07.2015, 16:10  [ТС] #2
Клиент:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
    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();
        }
    }
0
Anklav
440 / 299 / 46
Регистрация: 23.01.2013
Сообщений: 633
Завершенные тесты: 2
06.07.2015, 20:43 #3
Соединение может закрывается если его не использовать (Маршрутизаторы на пути могут забыть правила по которому передавать пакеты). Пингуйте сервер из клиента, раз в некоторое время.
0
Nowsoud
1 / 1 / 0
Регистрация: 01.01.2015
Сообщений: 90
07.07.2015, 11:58  [ТС] #4
И что делать, если при пинге сервер не ответил?
0
Anklav
440 / 299 / 46
Регистрация: 23.01.2013
Сообщений: 633
Завершенные тесты: 2
07.07.2015, 20:45 #5
Nowsoud, говорить, что сервер не отвечает. Не понял сути вопроса.

Добавлено через 30 минут
Как я понял проблема в том, что сервер перестает отвечать, после некоторого бездействия клиента. На сколько я знаю, обычно маршрутизаторы помнят правила около 30 сек (30 взял потому что при реализации long pooling обычно сервер держит соединение около 30 сек, а потом возвращает клиенту).

После не активности клиента, маршрутизаторы могут забыть правила по которым необходимо передавать пакет дальше, и пакет не дойдет до цели. Решение, это не допускать такого долгой не активности, с помощью пинг пакетов.
1
Nowsoud
1 / 1 / 0
Регистрация: 01.01.2015
Сообщений: 90
10.07.2015, 02:49  [ТС] #6
В том-то, как раз, и проблема. Никаких 30 секунд. Только что сообщение было принято сервером, а через 2 секунды уже никакие сообщения не принимаются. А потом исключение падает.
Я вообще не понимаю, как такое может быть. Попробую протестировать на других компьютерах.
Всем спасибо за советы.
0
10.07.2015, 02:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.07.2015, 02:49

Асинхронный сервер на сокетах.Как зациклить ?
Итак у меня есть код сервера который только принимает данные.Пожалуйста...

Асинхронный сервер - чат, много сообщений
вобщем сделал некое подобие чата, все вроде бы хорошо - отсылает/принимает...

Получить ip адрес клиента (асинхронный клиент - сервер)
Не могу получить ip адрес клиента (асинхронный клиент - сервер) при получении...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru