首页 新闻 会员 周边 捐助

异步Socket通信问题

0
悬赏园豆:5 [已关闭问题] 关闭于 2014-06-18 09:49

我写了一个异步sokcet客户端和服务器通信的例子,客户端循环的给服务器发消息,其实是检测心跳的功能,但是程序只能发送接收一次,客户端就抛异常了,说远程主机强迫关闭了一个现有连接,可是我服务器端也没有手动关闭socket,不知道为什么。

客户端:

 1  /// <summary>
 2         /// 发送心跳信息(客户端GUID)到客户端
 3         /// </summary>
 4         private void SendMsg()
 5         {
 6             sendSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
 7             System.Net.IPEndPoint IpPort = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("192.168.0.58"), int.Parse("9001"));
 8             try
 9             {
10                 sendSocket.Connect(IpPort);           
11                 while (true)
12                 {                                                             
13                     //sendSocket.Send(Encoding.UTF8.GetBytes(this.ClientID));
14                     byte[] data = Encoding.UTF8.GetBytes(this.ClientID);
15                     StateObject state = new StateObject();
16                     state.workSocket = sendSocket;
17                     Array.Copy(data, 0, state.buffer, 0, data.Length);
18                     sendSocket.BeginSend(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(SendCallback), state);
19                     PublicFunctions.LogExceptionMsg(ClientID, ClientName.GroupName, "", "", "", "0");
20                     System.Threading.Thread.Sleep(2000);                   
21                 }
22             }
23             catch (SocketException e)
24             {
25                 int s = e.ErrorCode;
26             }
27         }
28         private void SendCallback(IAsyncResult ar)
29         {
30             try
31             {
32                 StateObject handler = (StateObject)ar.AsyncState;
33                 Socket sendSocket = handler.workSocket;
34                 int bytesSent = sendSocket.EndSend(ar);
35                 //sendSocket.Shutdown(SocketShutdown.Both);
36                 //sendSocket.Close();
37             }
38             catch
39             {
40                                
41             }
42         }
View Code

服务器端:

 1 /// <summary>
 2         /// 启动监听
 3         /// </summary>
 4         private void ListenHeartBeat()
 5         {
 6             Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 7             IPEndPoint point = new IPEndPoint(IPAddress.Parse("192.168.0.58"), int.Parse("9001"));
 8             listenSocket.Bind(point);
 9             listenSocket.Listen(10);          
10             listenSocket.BeginAccept(new AsyncCallback(AcceptCallback), listenSocket);                
11         }
12         /// <summary>
13         /// 获得新连接的处理方法
14         /// </summary>
15         /// <param name="ar"></param>
16         private void AcceptCallback(IAsyncResult ar)
17         {           
18             Socket listener = (Socket)ar.AsyncState;
19             Socket handler = listener.EndAccept(ar);
20             // Create the state object.
21             StateObject state = new StateObject();
22             state.workSocket = handler;           
23             handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
24         }
25         /// <summary>
26         /// 接收数据的处理方法
27         /// </summary>
28         /// <param name="ar"></param>
29         private void ReceiveCallback(IAsyncResult ar)
30         {
31             String clientID = String.Empty;          
32             StateObject state = (StateObject)ar.AsyncState;
33             Socket handler = state.workSocket;
34             try
35             {
36                 int bytesRead = handler.EndReceive(ar);
37                 if (bytesRead > 0)
38                 {
39                     state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
40                     clientID = state.sb.ToString();
41                     if (clientID.Length == 36)
42                     {
43                         state.timeOutCount = 0;
44                         PublicFunctions.LogExceptionMsg(clientID,"", "", "", "", "1");
45                     }
46                     else
47                     {
48                         handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
49                     }
50                 }
51                 else
52                 {
53                     state.timeOutCount += 1;
54                 }
55                 if (state.timeOutCount > 3)
56                 {
57                     RemoveClient(clientID);
58                 }
59             }
60             catch
61             {                               
62             }
63         }
View Code

谁给看看哪里有问题。

冷水寒冰的主页 冷水寒冰 | 初学一级 | 园豆:0
提问于:2013-11-07 12:09
< >
分享
所有回答(3)
0

服务器端的问题,ReceiveCallback方法处理完第一次之后,应该继续等待处理客户端发送过来的数据

朝曦 | 园豆:1073 (小虾三级) | 2013-11-07 13:21
0

嗯,服务端应该一直有个监听

幕三少 | 园豆:1384 (小虾三级) | 2013-11-15 10:08
0

楼上说的对,在服务器端你要做一个循环来监听客户端的连接请求,否则,你现在的代码,在通信一次后,程序就返回了(通信通道被关闭),当有第二个客户端请求连接的时候,客户端就报你说的异常。

legendboys | 园豆:208 (菜鸟二级) | 2014-02-28 14:50
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册