I'm trying to implement code for rating movies using sockets, but server and client don't execute every my request. Is this way of implementation good? In one moment it looks as all is blocked. When I try to write a movie , do- while loop never stops. It is one more problem. Codes are below.
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map.Entry;
public class Server{
public static int test_port=12345;
private int port;
BufferedReader br;
PrintWriter toUser;
BufferedReader fromUser;
public static HashMap\<String,Double\> listOfMovies=new HashMap\<\>();
public static HashMap\<String,Integer\> counter=new HashMap\<\>();
public static void main(String\[\] args) {
// TODO Auto-generated method stub
Server server=new Server(Server.test_port);
server.execute();
}
private void execute() {
// TODO Auto-generated method stub
try(ServerSocket s=new ServerSocket(port)){
br=new BufferedReader(new InputStreamReader(new FileInputStream("Movies.txt")));
for(Entry<String,Double> m: listOfMovies.entrySet()) {
System.out.println(m.getKey()+" "+m.getValue());
}
while(true) {
Socket client=s.accept();
fromUser=new BufferedReader(new InputStreamReader(client.getInputStream()));
toUser=new PrintWriter(client.getOutputStream(),true);
System.out.println("Client connected!");
toUser.println("Welcome!");
toUser.println("Write movie that you want to rate:");
String line;
while((line=br.readLine())!=null) {
String movie=line;
listOfMovies.put(movie,0.0);
counter.put(movie, 0);
toUser.println(line);
}
toUser.println("Pick a movie:");
System.out.println(fromUser.readLine());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Server(int port) {
this.port=port;
}
}
package movies;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Scanner;
public class Client {
private String hostname;
private int port;
BufferedReader fromServer;
PrintWriter toServer;
ArrayList\<String\> list=new ArrayList\<String\>();
public static void main(String\[\] args) {
// TODO Auto-generated method stub
Client client=new Client("localhost",Server.test_port);
client.execute();
}
private void execute() {
// TODO Auto-generated method stub
try(Socket client=new Socket(this.hostname,this.port)){
System.out.println("Client connected to server: "+this.hostname);
fromServer=new BufferedReader(new InputStreamReader(client.getInputStream()));
toServer=new PrintWriter(client.getOutputStream(),true);
while(true) {
String line=fromServer.readLine();
while(line!=null) {
System.out.println(line);
list.add(line);
line=fromServer.readLine();
}
//fromServer.close();
//toServer.close();
toServer.println("ll");
System.out.println(list.contains("Kika"));
Scanner sc=new Scanner(System.in);
String movie=" ";
while(!list.contains(movie)) {
movie=sc.nextLine();
}
toServer.println(movie);
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Client(String hostname,int port) {
this.hostname=hostname;
this.port=port;
}
}
I don't understand why this code is not good. For example, these two lines
toServer.println("ll");
System.out.println(list.contains("Kika"));
do not anything.
Your application protocol design is broken. You are operating in 'line mode'. For a new connection, the server writes exactly 2 lines and then expects to receive lines.
toUser.println("Welcome!");
toUser.println("Write movie that you want to rate:");
String line;
while((line=br.readLine())!=null) ...
Meanwhile, your client code expects to receive an indefinite number of lines forever.
String line=fromServer.readLine();
while(line!=null) {
System.out.println(line);
list.add(line);
line=fromServer.readLine();
}
Only 'end of file' (connection closed) gets you out of that loop.
To fix, you have two options:
Have the client code 'know' (i.e., make the same assumptions) about what is going on. In other words, expect exactly two reads before it needs to write.
Add some protocol to say 'your turn to write'. (Simplistic approach: line saying 'OVER' !)