当我运行我相当简单的TCP服务器时,我注意到第一次尝试连接并发送对象时,我收到连接重置错误。如果我保持服务器运行但让客户端再次发送它一切正常。我在这里不知所措,是什么导致了这种行为?
客户端:
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);
}
}
我在每次请求后尝试关闭而不是从服务器关闭套接字。
如果我在没有循环的情况下运行客户端它似乎工作,我认为它最初失败但我无法重新创建它。
如果我尝试在循环中运行客户端,则第一次运行客户端时所有连接都将失败,但如果我重新启动客户端,则所有连接都将成功。
使用sleep(1000)暂停上面的循环将使所有连接成功。服务器无法处理快速连接尝试是否那么简单?我希望将请求处理放在单独的线程中将启用此功能。但为什么循环中的第一个连接也会失败?
此致 基督教
答案 0 :(得分:0)
所以最后我加入了这样的事情:
客户端:
try {
Socket connection = new Socket(mHostAddress, mHostPort);
connection.setSoTimeout(mTimeOut);
ObjectOutputStream outgoing = new ObjectOutputStream(
new BufferedOutputStream(connection.getOutputStream()
)); // <-- Opening output stream first in client (opposite to server)
outgoing.writeObject(mMessage);
outgoing.flush();
outgoing.close(); // <-- closing the stream as per EJP's comment
} catch (IOException ex) {
System.out.print("IOException in TCPSender: " + ex.getMessage());
}
服务器:
ExecutorService pool = Executors.newFixedThreadPool(mClientThreads);
try (ServerSocket server = new ServerSocket(mPort)) {
while (mRunning) {
final Socket client = server.accept();
client.setSoTimeout(mTimeOut);
pool.execute(() -> {
mMessageHandler.handle(client); // mMessageHandler = NetworkMessageHandler
});
}
} catch (IOException ex) {
System.out.println("IO Exception occurred in TCPServer: "
+ ex.getMessage());
} finally {
System.out.println("Server stopped...");
}
NetworkMessageHandler
try {
ObjectInputStream input = new ObjectInputStream(
new BufferedInputStream(aClient.getInputStream()) // Input first in server
);
NetworkMessage message = (NetworkMessage) input.readObject();
input.close(); // <-- closing stream
aClient.close(); // <-- making sure to close the Socket connection to client
act(message, sendersIP); <-- acting on the message from client
} catch (IOException ex) {
System.out.println("An IO exception occurred "
+ "in NetworkMessageHandler: " + ex.getMessage());
} catch (ClassNotFoundException ex) {
System.out.println("Could not recreate the sent class: "
+ ex.getMessage());
}
我确保我没有错过关闭我的溪流和插座,并按照this oracle tutorial提示了一些提示。
此致 基督教