C# 当远程主机断开连接时,Socket.Receive为什么会抛出SocketException(10054)?
我以前用C写套接字程序,不明白为什么会发生上述情况 我的服务器在接收调用时阻塞,当它返回0时,我中断while循环并关闭线程C# 当远程主机断开连接时,Socket.Receive为什么会抛出SocketException(10054)?,c#,.net,C#,.net,我以前用C写套接字程序,不明白为什么会发生上述情况 我的服务器在接收调用时阻塞,当它返回0时,我中断while循环并关闭线程 public class MyServer { public MyServer() { } public void Init() { ThreadPool.QueueUserWorkItem(StartListening); while (true) { Console.Read();
public class MyServer {
public MyServer() {
}
public void Init() {
ThreadPool.QueueUserWorkItem(StartListening);
while (true) {
Console.Read();
}
}
public void StartListening(Object state) {
// Establish the local endpoint for the socket.
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try {
// Bind the socket to the local endpoint and listen for incoming connections.
listener.Bind(localEndPoint);
listener.Listen(100);
while (true) {
Console.WriteLine("Waiting for a connection...");
// get connection
Socket client = listener.Accept();
// push client to another thread
ThreadPool.QueueUserWorkItem(HandleClient, client);
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
private void HandleClient(Object obj) {
// Get the socket that handles the client request.
Socket client = (Socket)obj;
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
try {
while (true) {
int bytesRead = client.Receive(state.buffer);
Console.WriteLine("bytesRead=" + bytesRead);
// remote dc.
if (bytesRead == 0)
break;
String content = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
client.Send(state.buffer, 0, state.buffer.Length, 0);
}
} catch (SocketException e) {
Console.WriteLine("SocketException : {0}", e.ToString());
}
client.Shutdown(SocketShutdown.Both);
client.Close();
}
private void Send(Socket handler, String data) {
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);
}
}
但是,当我单击客户端的close按钮x时,服务器的Receive调用抛出一个SocketException。根据,这不应该发生,因为我已经满足了上面提到的面向连接的部分和下面提到的客户端关闭部分的条件
Client.cs (pseudo):
public class MyClient {
public void Init() {
byte[] bytes = new byte[1024];
Socket sender = null;
try {
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);
sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
while (true) {
// Encode the data string into a byte array.
String input = Console.ReadLine();
byte[] msg = Encoding.ASCII.GetBytes(input);
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
}
} 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());
} finally {
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
}
}
我对finally blocks的肤浅理解是它将始终执行。但这里的情况似乎不是这样
那么,我做错了什么?我是否应该捕获异常,关闭服务器端的客户端套接字,然后继续,忽略它?但是我更喜欢不抛出异常。SocketException上的SocketErrorCode是什么?异常的错误代码是什么?另外:客户端有一个无限循环:这当然意味着它从不调用客户端关闭?因为服务器不发送,所以我不清楚客户端试图接收什么…10054,由对等方重置连接。客户端的清理在finally块中,当我关闭客户端时,不会执行吗?服务器会回显客户端发送给他的任何内容,但为了保持简洁,我省略了它。很抱歉,我解决了这个问题以澄清问题。根据我的经验,对于控制台应用程序,单击“x”立即结束程序。不再执行代码,即使最后阻塞。您应该为客户端进程被强制终止或网络连接中断的情况做好准备。