TCP。客户端连接,即使服务器不接受他
TCP. client connects even if server doesn't accept him
我有 TCP 服务器-客户端应用程序。它有效,但有时会发生一些事情。客户端连接到服务器,但服务器说他不接受他。
服务器端代码:
while(!stopped){
try {
AcceptClient();
} catch(SocketTimeoutException ex){
continue;
} catch (IOException ex) {
System.err.println("AppServer: Client cannot be accepted.\n"+ex.getMessage()+"\n");
break;
}
...
private void AcceptClient() throws IOException {
clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(200);
out = new ObjectOutputStream(clientSocket.getOutputStream());
in = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("Accepted connection from "+clientSocket.getInetAddress());
}
客户端代码:
try {
socket = new Socket(IPAddress, serverPort);
socket.setSoTimeout(5000);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e1) {
sendSystemMessage("DISCONNECTED");
sendSystemMessage(e1.getMessage());
return;
}
sendSystemMessage("CONNECTED");
如果客户端连接消息:
Accepted connection from ... appears. But sometimes it doesn't appear
even if client sends message "CONNECTED"
服务器仍在运行尝试获取客户端的循环,并且正在捕获 socketTimeoutException。客户端已连接,发送消息并等待响应。
我怀疑您客户的 'sendSystemMessage()' 中缺少 'flush'。
不幸的是,ObjectInputStream 的 constructor 试图从底层流中读取 header(恕我直言,这不是很直观)。因此,如果客户端无法刷新数据 - 服务器可能会卡在 "in = new ObjectInputStream(socket.getInputStream())"...
行
作为旁注,服务器通常为每个传入的客户端启动一个线程更好,但这只是一个旁注(加上它显然取决于要求)。
我发现了问题。我的网络上的通信速度太慢,因此在获取输入流时超时。该解决方案有两个部分。在获取输入流之前刷新输出流。并在流初始化后设置套接字超时。
服务器端:
clientSocket = serverSocket.accept();
out = new ObjectOutputStream(clientSocket.getOutputStream());
out.flush()
in = new ObjectInputStream(clientSocket.getInputStream());
clientSocket.setSoTimeout(200);
我有 TCP 服务器-客户端应用程序。它有效,但有时会发生一些事情。客户端连接到服务器,但服务器说他不接受他。
服务器端代码:
while(!stopped){
try {
AcceptClient();
} catch(SocketTimeoutException ex){
continue;
} catch (IOException ex) {
System.err.println("AppServer: Client cannot be accepted.\n"+ex.getMessage()+"\n");
break;
}
...
private void AcceptClient() throws IOException {
clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(200);
out = new ObjectOutputStream(clientSocket.getOutputStream());
in = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("Accepted connection from "+clientSocket.getInetAddress());
}
客户端代码:
try {
socket = new Socket(IPAddress, serverPort);
socket.setSoTimeout(5000);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e1) {
sendSystemMessage("DISCONNECTED");
sendSystemMessage(e1.getMessage());
return;
}
sendSystemMessage("CONNECTED");
如果客户端连接消息:
Accepted connection from ... appears. But sometimes it doesn't appear even if client sends message "CONNECTED"
服务器仍在运行尝试获取客户端的循环,并且正在捕获 socketTimeoutException。客户端已连接,发送消息并等待响应。
我怀疑您客户的 'sendSystemMessage()' 中缺少 'flush'。 不幸的是,ObjectInputStream 的 constructor 试图从底层流中读取 header(恕我直言,这不是很直观)。因此,如果客户端无法刷新数据 - 服务器可能会卡在 "in = new ObjectInputStream(socket.getInputStream())"...
行作为旁注,服务器通常为每个传入的客户端启动一个线程更好,但这只是一个旁注(加上它显然取决于要求)。
我发现了问题。我的网络上的通信速度太慢,因此在获取输入流时超时。该解决方案有两个部分。在获取输入流之前刷新输出流。并在流初始化后设置套接字超时。
服务器端:
clientSocket = serverSocket.accept();
out = new ObjectOutputStream(clientSocket.getOutputStream());
out.flush()
in = new ObjectInputStream(clientSocket.getInputStream());
clientSocket.setSoTimeout(200);