我正在尝试构建一个TCP转发器示例。以下是功能简介:
这一切都是用C写的。 客户端和目标服务器可以用任何语言编写,现在是Java。
当我第一次运行客户端时,它按预期工作。但是,如果我终止客户端并重新启动它,则服务器永远不会收到新连接。
这是我怀疑是错误的服务器代码。
Socket clientSocket = serverSocket.accept();
InputStream inputStream = clientSocket.getInputStream();
OutputStream outputStream = clientSocket.getOutputStream();
while (true) {
byte[] bArray = new byte[2048];
try {
System.out.println(String.format("SERVER:%s: Attempting to read", this.name));
inputStream.read(bArray);
System.out.println(String.format("SERVER:%s: Received %s", this.name, new String(bArray)));
byte[] bytes = (name + ":" + counter).getBytes();
counter++;
outputStream.write(bytes);
System.out.println(String.format("SERVER:%s: Sent %s", this.name, new String(bytes)));
} catch (IOException e) {
System.out.println(String.format("SERVER:%s: Client Disconnected ", this.name));
clientSocket = serverSocket.accept();
inputStream = clientSocket.getInputStream();
}
}
在C程序中,我检测到断开并关闭套接字,如下所示:
LOGINFO("Reading from Client Socket.");
iResult = read(readSocket, buff, recvbuflen);
if (iResult <= 0) {
LOGERROR("Receiving failed");
close(readSocket);
break;
}
答案 0 :(得分:1)
尝试使用并发来管理每个请求来修改服务器逻辑。通过这种方式,服务器将能够在一个线程中单独处理每个客户端。必须在相关的线程中执行读写数据。池线程范例通常用于避免线程开销[1]。
例如:
ExecutorService threadPool = Executors.newFixedThreadPool(n);
ServerSocket serverSocket = null;
//...
while(!isStopped()){
Socket clientSocket = null;
try {
clientSocket = this.serverSocket.accept();
threadPool.execute(new WorkerRunnable(clientSocket));
// Process data in the WorkerRunnable class
} catch (IOException e) {
if(isStopped()) {
System.err.println("Server Stopped.") ;
break;
}
throw new RuntimeException("Error accepting client connection", e);
}
}
可在此处找到精心设计的示例:http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html
答案 1 :(得分:1)
你应该使用
shutdown(socket_fd, SHUT_WR);
而不是close(socket_fd)
才能正确关闭套接字。
如果您使用SHUT_WR,FIN数据包将被发送到另一方通知他们我们没有更多数据要发送。