当我运行我相当简单的TCP服务器时,我注意到第一次尝试连接并发送一个对象时出现连接重置错误。如果我保持服务器运行,但让客户端再次发送它一切正常。我在这里亏本,这是什么原因造成的?为什么我的连接在我尝试写入Socket时第一次复位?
客户:
for (int i = 0; i < 3; i++) {
Socket s = new Socket("192.168.0.10", 9750);
SysIO.print("Connected: " + s.isConnected());
ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(s.getOutputStream()));
Object obj = new OneMessage("Hi there: " + i);
oos.writeObject(obj);
oos.flush();
sleep(1000); // <-- turns error on and off :/
}
服务器:
try (ServerSocket incomingSocket = new ServerSocket(mPort)) {
SysIO.print("Game Server started...");
incomingSocket.setSoTimeout(mTimeout);
while (mRunning) {
Socket clientConnection = null;
try {
clientConnection = incomingSocket.accept();
clientConnection.setSoTimeout(3000);
final Socket connection = clientConnection;
Thread requestHandlingThread = new Thread(() -> {
mRequestHandler.handleRequest(connection);
});
requestHandlingThread.start();
} catch (SocketTimeoutException ste) {
SysIO.print("TCP timeout...");
} catch (IOException ex) {
Logger.getLogger(TCPServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
} catch (BindException ex) {
SysIO.print("Could not bind: " + ex.getMessage());
} catch (IOException ex) {
SysIO.print("There was a problem with IO in TCP Server: " + ex.getMessage());
Logger.getLogger(TCPServer.class.getName()).log(Level.SEVERE, null, ex);
}
请求处理程序:
public void handleRequest(Socket aRequest) {
try {
SysIO.print("Connected: " + aRequest.isConnected());
ObjectInputStream ois = new ObjectInputStream(
new BufferedInputStream(aRequest.getInputStream()));
GameMessage message = (GameMessage) ois.readObject();
aRequest.close();
SysIO.print("Received: " + message.getType());
} catch (IOException | ClassNotFoundException ex) {
SysIO.print("IO exception: " + ex.getMessage());
Logger.getLogger(SimpleHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
我试着关闭和从服务器的每个请求后未关闭套接字。
如果我运行客户端没有循环它似乎工作,我认为它在第一次失败,但我不能重新创建它。
如果我尝试在循环中运行客户端,所有连接将在第一次运行客户端时失败,但如果我重新启动客户端,则所有连接都将成功。
让睡眠(1000)暂停上述循环将使所有连接成功。这很简单,服务器无法处理快速连接尝试?我希望把请求处理放在单独的线程中可以实现这一点。但为什么循环中的第一个连接也会失败?
问候, 基督教
对于读取超时,三秒钟是相当短的。至少应该有十个。您需要在循环结束时在客户端中使用'oos.close()'。 – EJP
NB'isConnected()'在你测试的时候不可能是假的。 – EJP