我写了一个异步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 }
服务器端:
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 }
谁给看看哪里有问题。
服务器端的问题,ReceiveCallback方法处理完第一次之后,应该继续等待处理客户端发送过来的数据
嗯,服务端应该一直有个监听
楼上说的对,在服务器端你要做一个循环来监听客户端的连接请求,否则,你现在的代码,在通信一次后,程序就返回了(通信通道被关闭),当有第二个客户端请求连接的时候,客户端就报你说的异常。