Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/16: Рейтинг темы: голосов - 16, средняя оценка - 4.56
320 / 280 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
1

Отладка TCP соединения

06.05.2013, 23:33. Показов 3164. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет. Народ, посмотрите со стороны на мой код, кто разбирается. У меня глючит клиентская часть TCP:
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
private IPHostEntry ipHost;
private IPAddress ipAddr;
private String Myip;
private IPEndPoint ipEndPoint;
private Socket sock;
 
private void Connect()
{
                ipHost = Dns.Resolve(ipAddr.ToString());
                ipAddr = ipHost.AddressList[0];
 
                ipEndPoint = new IPEndPoint(ipAddr, 11000);
 
                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.BeginConnect(ipEndPoint, new AsyncCallback(ConnectCallback), sock);
                
                SendServ("Client was started!");
                
                sock.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), sock);//второй раз эта функция уже не вызывается
                //ждем ответа и обрабатываем
                //для закрытия соединения вызываем: 
                SendServ("<end>");
}
 
public void ConnectCallback(IAsyncResult ar)
{
            try
            {
                Socket sclient = (Socket)ar.AsyncState;
                sclient.EndConnect(ar);
            }
            catch (Exception ex)
            {
 
            }
}
 
        public void SendServ(String sms)
        {
            try
            {
                byte[] msg = Encoding.Default.GetBytes(Dns.GetHostName()); 
                sock.BeginSend(msg, 0, msg.Length, 0, new AsyncCallback(SendCallback), sock); 
                SendDone.WaitOne(); 
                SendDone.Reset(); 
                string theMessage = sms;
                msg = Encoding.Default.GetBytes(theMessage); 
                sock.BeginSend(msg, 0, msg.Length, 0, new AsyncCallback(SendCallback), sock); 
                SendDone.WaitOne();
                if (theMessage.IndexOf("<end>") > -1) 
                {
                    sock.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), sock);
                    sock.Shutdown(SocketShutdown.Both); 
                    sock.Close();
                }
            }
            catch (Exception ex)
            {
 
            }
        }
        
        public void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket sclient = (Socket)ar.AsyncState;
                int bytesSent = sclient.EndSend(ar);
                SendDone.Set();
            }
            catch (Exception ex)
            {
                
            }
        }
        
        public void ReceiveCallback(IAsyncResult ar)
        {
            Socket sclient = (Socket)ar.AsyncState;
            int bytesRead = sclient.EndReceive(ar);
                if (bytesRead > 0)
                {
                    ...
                }
        }
Проблема в том, что первый запуск проходит идеально (начинается все с вызова Connect()), все подключается. После я закрываю соединение (тег <end>) и начинается петрушка. Снова вызываю Connect(), ConnectCallback-вызывается, а вот в ReceiveCallback уже не заходит. Каким-то необъяснимым образом эта программа работает через раз. Один раз она вторично не подключается, второй раз она подключается. Есть какие-нибудь мысли?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.05.2013, 23:33
Ответы с готовыми решениями:

Реализовать на tcp сокетах переподключение к tcp серверу в случае потери соединения
Всем привет, подскажите как можно реализовать на tcp сокетах переподключение к tcp серверу в случае...

Закрытие tcp соединения на хосте
Здравствуйте. Есть такая проблема: после разрыва соединения хост считает его открытым. Как мне...

Сцена зависает при запуске TCP-клиента, когда он подключен к TCP - серверу, при этом TCP-клиент полностью функционирует
Проблема описана в заголовке, и хотелось бы услышать ваше мнение, о том как можно решить проблему....

Не прерываются Tcp соединения
Здравствуйте. Пишу многопоточную программу и столкнулся с проблемой. Есть метод, он создает Tcp...

18
Эксперт .NET
1956 / 1417 / 335
Регистрация: 15.06.2012
Сообщений: 5,322
Записей в блоге: 3
07.05.2013, 10:04 2
Для начала....
C#
1
2
3
4
5
6
7
8
9
                sock.BeginConnect(ipEndPoint, new AsyncCallback(ConnectCallback), sock);
                
// Неправильно. у тебя BeginConnect вообще может не сработать, 
//но ты сразу же вызываешь следующий метод Отправки сообщения
                SendServ("Client was started!");
                
                sock.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), sock);
// тоже самое - запустил асинхронную отправку и тут же валишь сооединение в главном потоке. 
                SendServ("<end>");
Пустой catch, да ещё с (Exception ex) говорит о том, что "не знаю, но так делают умные дядьки". А теперь на пальцах: в блоке try возможна ошибка, но о её существовании никто никогда не узнает.

C#
1
2
3
4
5
6
7
8
9
            try
            {
                Socket sclient = (Socket)ar.AsyncState;
                sclient.EndConnect(ar);
            }
            catch (Exception ex)
            {
 
            }
0
320 / 280 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
07.05.2013, 18:58  [ТС] 3
Пустой catch, да ещё с (Exception ex) говорит о том, что "не знаю, но так делают умные дядьки". А теперь на пальцах: в блоке try возможна ошибка, но о её существовании никто никогда не узнает.
Не, я то как раз знаю. Я специально вырезал код, дабы вас не путать. Там дело в том, что эта функция работает во вторичном потоке, и "пачкать" код делегатами , которые выводят ошибки- не рационально. Я вырезал тот код, который имеет отношение к делу.
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
07.05.2013, 19:11 4
titans2011,
C#
1
2
3
SendServ("Client was started!");
                
                sock.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), sock);//второй раз эта функция уже не вызывается
Надо вызывать в ConnectCallback(IAsyncResult ar) , а не в начале подключения
0
320 / 280 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
07.05.2013, 19:34  [ТС] 5
Как попробую, отпишусь.

Добавлено через 21 минуту
Цитата Сообщение от EVG-1980 Посмотреть сообщение
titans2011,
C#
1
2
3
SendServ("Client was started!");
                
                sock.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), sock);//второй раз эта функция уже не вызывается
Надо вызывать в ConnectCallback(IAsyncResult ar) , а не в начале подключения
Так дело в том, что сокет там полностью закрывается. И потом заново открывается. Я как раз и заметил, что
C#
1
sock.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), sock);
Эта функция может вызваться, а может и не вызваться. Понимаете в чем загвоздка. Когда я посылаю:
C#
1
SendServ("Client was started!");
Я потом вызываю функцию sock.BeginReceive(...), т.к. сервер мне должен ответить, что мол все ок, продолжаем передачу. Делаю я таким методом (на сервере). Хотя я не уверен , что это правильно.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
                while (true)
                {
                    bytesRec = handler.Receive(bytes);
                    data = Encoding.Default.GetString(bytes, 0, bytesRec); 
 
                    uiContext.Send(d => listBox1.Items.Add(data), null); 
                    if (data.IndexOf("<end>") > -1) 
                        break;
                    if (data.IndexOf("Client was started!") > -1)
                    {
                        handler.Send(/*Типа все ок, продолжай*/);                 
                    }
                    
                }
                string theReply = "Сервер закрылся";
                byte[] msg = Encoding.Default.GetBytes(theReply); 
                handler.Send(msg); 
                handler.Shutdown(SocketShutdown.Both); 
                handler.Close();
Я видел, что в примере у препода sock.BeginReceive(...) вызывался все время, поэтому я и подумал, что таким образом я могу получить ответ от сервера, что все норм, продолжаем...
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
07.05.2013, 19:46 6
titans2011,

C#
1
2
3
4
5
6
7
8
public void ConnectCallback(IAsyncResult ar)
{
                Socket sclient = (Socket)ar.AsyncState;
                sclient.EndConnect(ar); // завершаем асинхронно соединение
                SendServ("Client was started!"); // отправляем серверу
                sock.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), sock);
                //ждем ответа и обрабатываем  (и не хера не обрабатываем)
}


А вот теперь обрабатываем

C#
1
2
3
4
5
6
public void ReceiveCallback(IAsyncResult ar)
{
Обработали  закрываем сокет и отключаемся  
 
SendServ("<end>"); -  не надо отсылать  при закрытии соединения сервер поучит пакет длинной 0 байт  достаточно сделать проверку на стороне сервера  if(byteread == 0) клиент отключился
}
Добавлено через 6 минут
titans2011, асинхронные операции выполняются в разных!!! потоках (т.е. фактически параллельно)

что делаешь ты
C#
1
2
3
4
5
6
 SendServ("Client was started!");
                
                sock.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), sock);//второй раз эта функция уже не вызывается
                //ждем ответа и обрабатываем
                //для закрытия соединения вызываем: 
                SendServ("<end>");   //  ЭТА ШТУКА МОЖЕТ СРАБОТАТЬ БЫСТРЕЕ  чем ты получишь данные
0
320 / 280 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
07.05.2013, 20:27  [ТС] 7
Цитата Сообщение от EVG-1980 Посмотреть сообщение
titans2011, асинхронные операции выполняются в разных!!! потоках (т.е. фактически параллельно)

что делаешь ты
C#
1
2
3
4
5
6
 SendServ("Client was started!");
                
                sock.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), sock);//второй раз эта функция уже не вызывается
                //ждем ответа и обрабатываем
                //для закрытия соединения вызываем: 
                SendServ("<end>");   //  ЭТА ШТУКА МОЖЕТ СРАБОТАТЬ БЫСТРЕЕ  чем ты получишь данные
Исключено. Прежде всего я жду ответа. Если он не приходит, то значит сокеты закрыты(и я не отсылаю <end> ). Если ответ пришел, то только потом я отсылаю закрытие (фактически у меня там стоит while(true)).
P.S. Я попробую ту штуку, что ты мне говорил. Потом отпишусь как будет работать.
0
Эксперт .NET
1956 / 1417 / 335
Регистрация: 15.06.2012
Сообщений: 5,322
Записей в блоге: 3
07.05.2013, 20:34 8
Цитата Сообщение от titans2011 Посмотреть сообщение
Эта функция может вызваться, а может и не вызваться.
Угу. А всё из-за того, что ты выполняешь всё сразу в кучи потоках: и соединение, и отправку, и прием, и закрытие. И если закрытие сработает быстрее всех, то будет "пушной зверь песец", причем о его существовании будет знать только... да никто не будет знать, ты же всё в try-catch позасовывал без должной обработки, вот и страдаешь.

В общем - EVG-1980 вроде как уже всё объяснил.
0
320 / 280 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
07.05.2013, 21:06  [ТС] 9
Цитата Сообщение от Wolfdp Посмотреть сообщение
Угу. А всё из-за того, что ты выполняешь всё сразу в кучи потоках: и соединение, и отправку, и прием, и закрытие. И если закрытие сработает быстрее всех, то будет "пушной зверь песец", причем о его существовании будет знать только... да никто не будет знать, ты же всё в try-catch позасовывал без должной обработки, вот и страдаешь.

В общем - EVG-1980 вроде как уже всё объяснил.
Я безусловно сделаю все выше сказанные советы. Но. Проблемы как я говорил в передачи нет. Проблема возникает, когда я закрываю сокет, а потом снова вызываю Connect() и все остальное. Посмотрим, что будет после изменения.
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
07.05.2013, 21:19 10
titans2011, По твоему коду видно что ты пытаешься соединиться, отправить, получить данные и закрыть соединение ОДНОВРЕМЕННО

Сначала надо соединиться

Connect() начинаем соединяться

ConnectCallback(IAsyncResult ar)
{
Соеденились

send () - начинаем отправлять данные
}

SendCallback(IAsyncResult ar)
{
Отправили данные

recive () - встаем на прием
}


ReceiveCallback(IAsyncResult ar)
{
принимаем данные

socket.close() - закрываем сокет
Connect() начинаем соединяться
}
0
320 / 280 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
07.05.2013, 21:32  [ТС] 11
Цитата Сообщение от EVG-1980 Посмотреть сообщение
titans2011, По твоему коду видно что ты пытаешься соединиться, отправить, получить данные и закрыть соединение ОДНОВРЕМЕННО
Я же говорю, там стоят вечные циклы (я их вырезал). Пока не пройдет соединение, отправить данные не получится и т.д. Можете не беспокоится. Там все идет своим чередом. Дело лишь во втором подключении.
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
07.05.2013, 21:37 12
titans2011, набери в гугле , асинхронные сокеты или асинхронный сервер почитай
0
Эксперт .NET
1956 / 1417 / 335
Регистрация: 15.06.2012
Сообщений: 5,322
Записей в блоге: 3
07.05.2013, 23:40 13
Цитата Сообщение от titans2011 Посмотреть сообщение
Я же говорю, там стоят вечные циклы
у-у-у-у-у... Скажу только одно - нужно лицезреть весь этот ужас, чтобы понять что не так.

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
        static void Main(string[] args)
        {
            Thread t = new Thread(server);
            t.IsBackground = true;
            t.Start();
 
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint ep = new IPEndPoint(IPAddress.Loopback, 0);
            s.Bind(ep);
            s.Connect(IPAddress.Loopback, 12000);
            s.Send(new byte[8]);
            s.Receive(new byte[8]);
            s.Close();
 
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ep = new IPEndPoint(IPAddress.Loopback, 0);
            s.Bind(ep);
            s.Connect(IPAddress.Loopback, 12000);
            s.Send(new byte[8]);
            s.Receive(new byte[8]);
            s.Close();
 
            Console.Write("Complite");
            Console.ReadKey();
        }
 
 
        static void server()
        {
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint ep = new IPEndPoint(IPAddress.Loopback, 12000);
            s.Bind(ep);
            s.Listen(10);
 
            Socket s1 = s.Accept();
            s1.Receive(new byte[8]);
            s1.Send(new byte[8]);
            Socket s2 = s.Accept();
            s2.Receive(new byte[8]);
            s2.Send(new byte[8]);
        }
0
320 / 280 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
08.05.2013, 09:26  [ТС] 14
Цитата Сообщение от Wolfdp Посмотреть сообщение
у-у-у-у-у... Скажу только одно - нужно лицезреть весь этот ужас, чтобы понять что не так.
Вот не нужно драматизировать. Я находил примеры в MSDN, где ожидание делалось с помощью семафоров. Но ведь если будет семафор, то ожидание будет вечным, если не подключится. А для времени, нужно вводить новый поток, который переключит через пару секунд этот семафор. Не проще ли в том же потоке поставить вечный цикл, отсчитать кол-во секунд в нем, и если нет подключения- выйти из вечняка? Мне кажется это на много проще.
Цитата Сообщение от Wolfdp Посмотреть сообщение
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
        static void Main(string[] args)
        {
            Thread t = new Thread(server);
            t.IsBackground = true;
            t.Start();
 
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint ep = new IPEndPoint(IPAddress.Loopback, 0);
            s.Bind(ep);
            s.Connect(IPAddress.Loopback, 12000);
            s.Send(new byte[8]);
            s.Receive(new byte[8]);
            s.Close();
 
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ep = new IPEndPoint(IPAddress.Loopback, 0);
            s.Bind(ep);
            s.Connect(IPAddress.Loopback, 12000);
            s.Send(new byte[8]);
            s.Receive(new byte[8]);
            s.Close();
 
            Console.Write("Complite");
            Console.ReadKey();
        }
 
 
        static void server()
        {
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint ep = new IPEndPoint(IPAddress.Loopback, 12000);
            s.Bind(ep);
            s.Listen(10);
 
            Socket s1 = s.Accept();
            s1.Receive(new byte[8]);
            s1.Send(new byte[8]);
            Socket s2 = s.Accept();
            s2.Receive(new byte[8]);
            s2.Send(new byte[8]);
        }
К стати да. Очень близко к тому, что нужно.
0
Эксперт .NET
1956 / 1417 / 335
Регистрация: 15.06.2012
Сообщений: 5,322
Записей в блоге: 3
08.05.2013, 13:31 15
Цитата Сообщение от titans2011 Посмотреть сообщение
Вот не нужно драматизировать.
Я не драматизирую, а говорю, что "фиг поймешь что там не так". А из увиденного, могу сказать только, что непонятно зачем используются асинхронные методы в сочетании с синхронными.
0
320 / 280 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
08.05.2013, 14:14  [ТС] 16
Значит причесал я более менее код-модель. Осталось одна деталь непонятная. Что бы у вас запустился мой код, нужно в начале клиента поменять IP сервера.
Клиент:
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
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
 
// State object for receiving data from remote device.
public class StateObject
{
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 256;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
}
 
public class AsynchronousClient
{
    // The port number for the remote device.
    private const int port = 11000;
 
    // ManualResetEvent instances signal completion.
    private static ManualResetEvent connectDone =new ManualResetEvent(false);
    private static ManualResetEvent sendDone =new ManualResetEvent(false);
    private static ManualResetEvent receiveDone =new ManualResetEvent(false);
 
    // The response from the remote device.
    private static String response = String.Empty;
 
    private static void StartClient()
    {
        // Connect to a remote device.
        try
        {
            IPAddress ipAddress;
            IPAddress.TryParse("192.168.1.164", out ipAddress);//укажите тут ваш адрес
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
 
            // Create a TCP/IP socket.
            Socket client = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
 
            // Connect to the remote endpoint.
            client.BeginConnect(remoteEP,new AsyncCallback(ConnectCallback), client);
            connectDone.WaitOne();
 
            // Send test data to the remote device.
            Send(client, "This is a test <with message><EOF>");
            sendDone.WaitOne();
 
            // Receive the response from the remote device.
            Receive(client);
            receiveDone.WaitOne();
 
            // Write the response to the console.
            Console.WriteLine("Response received : {0}", response);
 
 
 
            // Release the socket.
            client.Shutdown(SocketShutdown.Both);
            client.Close();
 
            if (response.IndexOf("Error authorize")!=-1)
            {
                Console.WriteLine("Типа логин и пароль не правильный!");
            }
            if (response.IndexOf("All right")!=-1)
            {
                Console.WriteLine("Типа продолжаем передачу!");
                remoteEP = new IPEndPoint(ipAddress, port);
                client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                
                connectDone = new ManualResetEvent(false);
                sendDone = new ManualResetEvent(false);
                receiveDone = new ManualResetEvent(false);
 
                client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();
 
                Send(client, "Ok, <without message>,<1:"+DateTime.Now.ToString()+"><er>\r\n");
                sendDone.WaitOne();
                Send(client, "Ok, <without message>,<2:" + DateTime.Now.ToString() + "><er>\r\n");
                sendDone.WaitOne();
                Send(client, "Ok, <without message>,<3:" + DateTime.Now.ToString() + "><EOF>");
                sendDone.WaitOne();
 
                Receive(client);
                receiveDone.WaitOne();
 
                Console.WriteLine("Response received : {0}", response);
            }
 
 
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
 
    private static void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;
 
            // Complete the connection.
            client.EndConnect(ar);
 
            Console.WriteLine("Socket connected to {0}",
                client.RemoteEndPoint.ToString());
 
            // Signal that the connection has been made.
            connectDone.Set();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
 
    private static void Receive(Socket client)
    {
        try
        {
            // Create the state object.
            StateObject state = new StateObject();
            state.workSocket = client;
 
            // Begin receiving the data from the remote device.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
 
    private static void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the state object and the client socket 
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;
 
            // Read data from the remote device.
            int bytesRead = client.EndReceive(ar);
 
            if (bytesRead > 0)
            {
                // There might be more data, so store the data received so far.
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
 
                // Get the rest of the data.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            else
            {
                // All the data has arrived; put it in response.
                if (state.sb.Length > 1)
                {
                    response = state.sb.ToString();
                }
                // Signal that all bytes have been received.
                receiveDone.Set();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
 
    private static void Send(Socket client, String data)
    {
        // Convert the string data to byte data using ASCII encoding.
        byte[] byteData = Encoding.ASCII.GetBytes(data);
 
        // Begin sending the data to the remote device.
        client.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), client);
    }
 
    private static void SendCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;
 
            // Complete sending the data to the remote device.
            int bytesSent = client.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to server.", bytesSent);
 
            // Signal that all bytes have been sent.
            sendDone.Set();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
 
    public static int Main(String[] args)
    {
        StartClient();
        return 0;
    }
}
И сервер:

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
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
 
// State object for reading client data asynchronously
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);
    //private static String sn = "Error authorize";
    private static String sn = "All right";
 
    public AsynchronousSocketListener()
    {
    }
 
    public static void StartListening()
    {
        // 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".
        IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
 
        // 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;
 
        // 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.ASCII.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 || content.IndexOf("<er>") > -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.
                if (content.IndexOf("<EOF>") > -1)
                {
                    if (content.IndexOf("<with message>") > -1)
                        Send(handler, sn);
                    if (content.IndexOf("<without message>") > -1)
                        Send(handler, "Server recived data and was closed");                    
                }
                else
                {
                    content = "";
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                }
 
            }
            else
            {
                // Not all data received. Get more.
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state);
            }
        }
    }
 
    private static void Send(Socket handler, String data)
    {
        // Convert the string data to byte data using ASCII encoding.
        byte[] byteData = Encoding.ASCII.GetBytes(data);
 
        // 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();
 
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
 
 
    public static int Main(String[] args)
    {
        StartListening();
        return 0;
    }
}
Я не могу одного понять. Почему когда я даю команды:
C#
1
2
3
4
5
6
                Send(client, "Ok, <without message>,<1:"+DateTime.Now.ToString()+"><er>\r\n");
                sendDone.WaitOne();
                Send(client, "Ok, <without message>,<2:" + DateTime.Now.ToString() + "><er>\r\n");
                sendDone.WaitOne();
                Send(client, "Ok, <without message>,<3:" + DateTime.Now.ToString() + "><EOF>");
                sendDone.WaitOne();
Сервер, вместо того, что бы очищать буфер с каждым приемом, он его накапливает. Как сбросить этот буфер? Т.к. в реальности я буду посылать очень много таких сообщений, и буфер точно переполниться.

Добавлено через 6 минут
Вот эта строка отсылает буфер. Где-то тут нужно сбрасывать его.
C#
1
 handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
Добавлено через 5 минут
Все, уже разобрался.
0
Эксперт .NET
1956 / 1417 / 335
Регистрация: 15.06.2012
Сообщений: 5,322
Записей в блоге: 3
08.05.2013, 14:25 17
Последовательный алгоритм через асинхроные методы путем ManualResetEvent, для "синхронизации"... Сохраню на память. XD
0
320 / 280 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
08.05.2013, 14:36  [ТС] 18
Ну блин. Это не я придумал. Это пример с MSDN
0
Эксперт .NET
1956 / 1417 / 335
Регистрация: 15.06.2012
Сообщений: 5,322
Записей в блоге: 3
08.05.2013, 14:41 19
titans2011, забей, преподу будешь это объяснять (или кому там будешь сдавать это чудо).

И блин - каюсь, но помочь с "этим" не могу: мой мозг тупо кричит "ПЕРЕПИСАТЬ" и ни в какую не хочет искать возможные баги.
0
08.05.2013, 14:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.05.2013, 14:41
Помогаю со студенческими работами здесь

Обрыв TCP соединения
Здравствуйте, уважаемые! У нас что-то непонятное происходит, требуется совет профессионала,...

Получить TCP/UDP соединения для процесса
Хочу получить TCP/UDP соединения, а также определить к какаим процессам они относятся......

Проверка соединения TCP
Привет всем! Пишу MODBUS/TCP-клиент на QNX(POSIX) (есть основной и резервный канал до сервера), с...

Обрыв соединения, TCP
Доброго времени всем. При реализации TCP сервера и клиента нужно организовать своевременное...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru