我曾经用C编写套接字程序,无法理解上述原因。
我的服务器在接收调用时阻塞,当它返回0时,我会跳出while循环并关闭该线程。
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);
}
}
但是,当我单击客户端的关闭按钮(“x”)时,服务器的Receive调用将抛出SocketException。根据{{3}},这不应该发生,因为我已经满足了面向连接的部分(见上文)和客户端关闭部分(见下文)条件。
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块的浅层理解是它将始终执行。但这似乎并非如此。
那么,我在这里做错了什么?我是否应该捕获异常,关闭服务器端的客户端套接字然后继续,忽略它?但我更愿意,如果没有抛出异常。