Reputation: 8096
I am trying to build a sample TCP Forwarder. Here is the functionality in brief:
All this is written in C. The Client and Target servers can be written in any language, right now its Java.
When I run a client for the first time, it works as expected. However, if I kill the client and restart it, the server never receives the new connection.
Here is my server code which I suspect is fault.
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();
}
}
In the C program, I detect the disconnection and close the socket as shown below:
LOGINFO("Reading from Client Socket.");
iResult = read(readSocket, buff, recvbuflen);
if (iResult <= 0) {
LOGERROR("Receiving failed");
close(readSocket);
break;
}
Upvotes: 1
Views: 319
Reputation: 2216
You should use
shutdown(socket_fd, SHUT_WR);
instead of close(socket_fd)
in order to properly close socket.
If you use SHUT_WR, a FIN packet will be sent to another side to inform them we don't have more data to send.
Upvotes: 0
Reputation: 342
Try to modify your server logic by using concurrency to manage each request. In this way, server will be able to handle each client separately in a thread. Reading and writing data must be performed in the related thread. A pool thread paradigm is often used to avoid thread overhead[1].
For example:
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);
}
}
A well designed example can be found here: http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html
Upvotes: 1