异步服务器套接字C#继续发送消息 [英] asynchronous server socket C# continue sending messages
问题描述
我有以下Sockets服务器,该服务器可以异步运行,
接受一次连接的多个客户端.我从微软那里得到的
网站.
我在示例代码中对
的配置做了一些修改.
IPAddress和端口.
Hi, I have the following Sockets server, which works asynchronously and
accepts multiple clients connected at once. I got it from the microsoft
website.
I made slight modifications in the example code, in the configuration of
the IPAddress and port.
1. using System;
2. using System.Net;
3. using System.Net.Sockets;
4. using System.Text;
5. using System.Threading;
6.
7. // State object for reading client data asynchronously
8. public class StateObject
9. {
10. // Client socket.
11. public Socket workSocket = null;
12. // Size of receive buffer.
13. public const int BufferSize = 1024;
14. // Receive buffer.
15. public byte[] buffer = new byte[BufferSize];
16. // Received data string.
17. public StringBuilder sb = new StringBuilder();
18. }
19.
20. public class AsynchronousSocketListener
21. {
22.
23. // Incoming data from client.
24. public static string data = null;
25.
26. // Thread signal.
27. public static ManualResetEvent allDone = new
ManualResetEvent(false);
28.
29. public AsynchronousSocketListener()
30. {
31. }
32.
33. public static void StartListening()
34. {
35. // Data buffer for incoming data.
36. byte[] bytes = new Byte[1024];
37.
38. // Establish the local endpoint for the socket.
39. // The DNS name of the computer
40. // running the listener is "host.contoso.com".
41. IPAddress ipAddress =
Dns.GetHostEntry("192.168.1.33").AddressList[2];
42. IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 4070);
43.
44. // Create a TCP/IP socket.
45. Socket listener = new Socket(AddressFamily.InterNetwork,
46. SocketType.Stream, ProtocolType.Tcp);
47.
48. // Bind the socket to the local endpoint and listen for
incoming connections.
49. try
50. {
51. listener.Bind(localEndPoint);
52. listener.Listen(100);
53.
54. while (true)
55. {
56. // Set the event to nonsignaled state.
57. allDone.Reset();
58.
59. // Start an asynchronous socket to listen for
connections.
60. Console.WriteLine("Waiting for a connection...");
61. listener.BeginAccept(
62. new AsyncCallback(AcceptCallback),
63. listener);
64.
65. // Wait until a connection is made before
continuing.
66. allDone.WaitOne();
67. }
68.
69. }
70. catch (Exception e)
71. {
72. Console.WriteLine(e.ToString());
73. }
74.
75. Console.WriteLine("\nPress ENTER to continue...");
76. Console.Read();
77.
78. }
79.
80. public static void AcceptCallback(IAsyncResult ar)
81. {
82. // Signal the main thread to continue.
83. allDone.Set();
84.
85. // Get the socket that handles the client request.
86. Socket listener = (Socket)ar.AsyncState;
87. Socket handler = listener.EndAccept(ar);
88.
89. // Create the state object.
90. StateObject state = new StateObject();
91. state.workSocket = handler;
92. handler.BeginReceive(state.buffer, , StateObject.BufferSize,
,
93. new AsyncCallback(ReadCallback), state);
94. }
95.
96. public static void ReadCallback(IAsyncResult ar)
97. {
98. String content = String.Empty;
99.
100. // Retrieve the state object and the handler socket
101. // from the asynchronous state object.
102. StateObject state = (StateObject)ar.AsyncState;
103. Socket handler = state.workSocket;
104.
105. // Read data from the client socket.
106. int bytesRead = handler.EndReceive(ar);
107.
108. if (bytesRead > )
109. {
110. // There might be more data, so store the data received
so far.
111. state.sb.Append(Encoding.ASCII.GetString(
112. state.buffer, , bytesRead));
113.
114. // Check for end-of-file tag. If it is not there, read
115. // more data.
116. content = state.sb.ToString();
117. if (content.IndexOf("\n") > -1)
118. {
119. // All the data has been read from the
120. // client. Display it on the console.
121. Console.WriteLine("Read {0} bytes from socket. \n
Data : {1}",
122. content.Length, content);
123. // Echo the data back to the client.
124. Send(handler, content);
125. }
126. else
127. {
128. // Not all data received. Get more.
129. handler.BeginReceive(state.buffer, ,
StateObject.BufferSize, ,
130. new AsyncCallback(ReadCallback), state);
131. }
132. }
133. }
134.
135. private static void Send(Socket handler, String data)
136. {
137. // Convert the string data to byte data using ASCII
encoding.
138. byte[] byteData = Encoding.ASCII.GetBytes(data);
139.
140. // Begin sending the data to the remote device.
141. handler.BeginSend(byteData, , byteData.Length, ,
142. new AsyncCallback(SendCallback), handler);
143. }
144.
145. private static void SendCallback(IAsyncResult ar)
146. {
147. try
148. {
149. // Retrieve the socket from the state object.
150. Socket handler = (Socket)ar.AsyncState;
151.
152. // Complete sending the data to the remote device.
153. int bytesSent = handler.EndSend(ar);
154. Console.WriteLine("Sent {0} bytes to client.",
bytesSent);
155.
156. handler.Shutdown(SocketShutdown.Both);
157. handler.Close();
158.
159. }
160. catch (Exception e)
161. {
162. Console.WriteLine(e.ToString());
163. }
164. }
165.
166.
167. public static int Main(String[] args)
168. {
169. StartListening();
170. return ;
171. }
172. }
173.
但是,按照这种方式,客户端将连接到该服务器并发送一个
信息.服务器读取它,然后断开与客户端的连接.我需要那个
客户端仍处于连接状态,并且可以继续发送许多消息,因为它
想要.
一方面,我知道我必须删除
的以下几行
SendCallBack方法,以便客户端仍处于连接状态:
However, the way it is, the client connects to this server and send a
message. The server reads it, and then disconnect the client. I need that
the client is still connected, and can continue to send many messages as it
wants.
On one hand I know that I have to remove the following lines of
SendCallBack method, so that the client is still connected:
<pre lang="midl">handler.Shutdown (SocketShutdown.Both)
handler.Close ();
无论如何,如何使客户端能够继续发送消息?做
我必须添加一个循环吗?在哪里?
谢谢!
Anyway, How can I do to enable the client to continue sending messages? Do
I must add a loop? Where?
Thanks!
推荐答案
查看标有"new"的行-您已经非常接近工作的代码了.
See the lines marked with "new" - You''re pretty close to a working piece of code already.
124. Send(handler, content);
new. // All data received. Get next message.
new. handler.BeginReceive(state.buffer,StateObject.BufferSize,
new. new AsyncCallback(ReadCallback), state);
125. }
126. else
127. {
128. // Not all data received. Get more.
129. handler.BeginReceive(state.buffer,StateObject.BufferSize,
130. new AsyncCallback(ReadCallback), state);
正如您得出的结论-不要在Send方法中关闭连接,请等到客户端发送关闭"消息.
问候
Espen Harlinn
And as you concluded - don''t close the connection in the Send method, wait until the client sends a "close" message.
Regards
Espen Harlinn
不,请不要使用循环.使用计时器创建一种轮询机制.
No dont use a loop. Creating a polling sort of a maechanism using a timer.
这篇关于异步服务器套接字C#继续发送消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!