The while loop doesn't terminate because inFromServer
is expecting more data. You need to close the connection (outToClient
) on the server side so that the client can be sure there is no more data coming.
Close socket connection after receiving stream - java
-
15-03-2022 - |
Question
I made a tcp server which takes a file name from the client and read the content of the file located on the server and then stream it back to the client.
I also made a client to receive the file. My problem is after receiving the file on the client, how do i terminate the loop, so i can close the connection?
Here is the server code:
import java.io.*;
import java.net.*;
import java.util.*;
public class WebTCPServer_file {
public static void main(String argv[]) throws Exception{
String request;
ServerSocket welcomeSocket = new ServerSocket(6790); //opening socket
while(true){
Socket connectionSocket = welcomeSocket.accept();
Scanner inFromClient = new Scanner(connectionSocket.getInputStream());
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
request = inFromClient.nextLine(); //client request
System.out.println("Received: "+request);
/*dividing request command*/
String reqMeth = request.substring(0, 3);
String reqURL = request.substring(5, (request.lastIndexOf("HTTP/1.1")));
String reqProto = request.substring(request.indexOf("HTTP/1.1"));
System.out.println("Request Method:\t" +reqMeth +"\nRequest URL:\t" +reqURL+ "\nRequest Protocol: " +reqProto);
File localFile = new File(reqURL.trim());
FileReader in = new FileReader(localFile);
BufferedReader inBuff = new BufferedReader(in);
String c;
while((c = inBuff.readLine())!=null){
outToClient.writeBytes(c + '\n');
System.out.println(c);
} //END while
outToClient.flush();
in.close();
} //END while(true)
} //END main
} //END class
Here is the client code:
import java.io.*;
import java.net.*;
import java.util.*;
public class TCPClient_file {
public static void main(String[] args) throws Exception{
String sentence ;
Scanner inFromUser = new Scanner(System.in);
Socket clientSocket = new Socket("192.168.0.16", 6790);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
sentence = inFromUser.nextLine();
outToServer.writeBytes(sentence + '\n');
String serverfile;
while ((serverfile = inFromServer.readLine()) != null)
System.out.println(serverfile);
inFromServer.close();
outToServer.close();
clientSocket.close();
} //END main
} //END class
Client request from server as such:
GET /domains.txt HTTP/1.1
where "domains.txt" is a file on server containing a list of websites.
Solution
OTHER TIPS
One crude of achieving this is to send a trigger [String from server], after sending all the data to client, indicating completion of file transfer, at the client side you can check for this string and upon receiveing this string you can come out of your while loop and can close connection.
Another better approach is, at the server-side before sending the actual file content send the size of the file and then the actual file data, on the client side keep track of bytes read, once you have read the byte equal to size posted earlier you can terminate your while loop