當我運行我相當簡單的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