2

First i'm sorry for my english. :-) It's my first post here.

I have application, something like torrent. I run it in one computer but 2 or more instance. i must ask user what file he want, and send this file to client. if i want its be host-to-host or multi-host. and my problem is: when i send to client list file in directory , he choose one of them and send to server nameFile. then server send this file to client. But when i send listFile i must close bufferedreader because readline() is blocking. but if i close that i don't have connection. Any idea? please for any proposition. this is my code:

Server:

public class Server extends Thread {

    private Socket s;
    int numerKlienta;
    String line;
    List<String> list = new ArrayList();

    private ServerSocket serverSocket;
    String nazwaPliku = "";
    PrintWriter outToClient;
    String text = "";
    String tmp = "";

    public Server(int port) throws Exception {

        serverSocket = new ServerSocket(port);
        while (true) {

            Socket clientSocket = serverSocket.accept();
            BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            outToClient = new PrintWriter(clientSocket.getOutputStream(), true);

            String path = "C:\\Users\\Ania\\Desktop";



            File directory = new File(path);

            File[] files = directory.listFiles();

            for (int j = 0; j < files.length; j++) {
                if (files[j].isFile()) {

                    text = files[j].getName();


                    outToClient.println(text);

                }

            }

            //outToClient.flush();
            outToClient.close();      //i must close beacuse in client when           i writeBytes its blocking next steps

            nazwaPliku = inFromClient.readLine();
            System.out.println(nazwaPliku);

            outToClient.close();
        }

    }


}

Client:

public class Client {




    public Client(String host, int port) throws Exception{

             s = new Socket(host, port);


             DataOutputStream   outToServer= new DataOutputStream(s.getOutputStream());

    BufferedReader inFromServer =
             new BufferedReader(new
             InputStreamReader(s.getInputStream())); 

    System.out.println("lista plików w katalogu : ");
    while ((( odpowiedz = inFromServer.readLine()) != null)){  


     System.out.println( odpowiedz);
    }

    //here is blocking and stop 



        System.out.println(" Jaki plik chcesz przesłać? podaj pełną nazwę");
        Scanner sc= new Scanner(System.in);
        String nazwaPliku=sc.next();
            outToServer.writeBytes(nazwaPliku);
        //saveFile(nazwaPliku);

    }

And my Main:

public class Main {

    public static void main(String[] args) throws Exception {

        Server serwer=null;
        System.out.println("Czy czy chcesz rozpocząc pracę jako serwer? (t/n)");
        Scanner sc = new Scanner(System.in);
        String odpowiedz = sc.next();
        if (odpowiedz.equals("t")) {

            System.out.println(" Na jakim porcie rozpocząc nasłuch?");
            sc = new Scanner(System.in);
            int portSerwera = sc.nextInt();
             serwer = new Server(portSerwera);
            //serwer.start();


        } 
        else{

            System.out.println("Czy chcesz rozpocząc połączenie z jakimś serwerem? (t/n)");
            sc = new Scanner(System.in);
            odpowiedz = sc.next();

            if (odpowiedz.equals("t")) {

                System.out.println("podaj numer portu do połączenia z serwerem");
                sc = new Scanner(System.in);
                int portKlienta = sc.nextInt();
                Client fc = new Client("localhost", portKlienta);
leeor
  • 17,041
  • 6
  • 34
  • 60
Ania.K
  • 31
  • 3
  • 1
    Nothing requires you to close the TCP stream. Just send a special line which means you have reached the end of the file. – Peter Lawrey Dec 30 '15 at 20:45
  • 1
    @PeterLawrey Not feasible. You would have to choose a line that could not possibly occur in any file. You would need at a minimum an escape protocol. – user207421 Dec 30 '15 at 22:34
  • @EJP True, This is what I meant by special. You can either, use characters which by definition invalid. Use a byte encoding which isn't valid text, or a simple escape sequence such as '.' by itself with an extra '.' if the line starts with a '.' – Peter Lawrey Dec 30 '15 at 23:58
  • Peter Lawrey, thx, it's working. I send special lines "end" :-) – Ania.K Dec 31 '15 at 10:16

1 Answers1

1

You need to design a protocol with structured messages, instead of just sending lines. The client must know when a message ends.

For example you could decide to end your list of files by sending an empty line (1).

When the client reads the files, when it received the empty line, it knows that the list is terminated, and that it's up to the client to now send its choice.

Using separators is one way of doing. Another way can be to send "packets", where each packet starts with a number of bytes or characters to expect in the packet. The client thus knows that it must read N bytes to read the entire packet, and that once the packet is read, it should send its choice, and then read another packet (2).

(1) and (2): note that these two strategies are used by the protocol you probably use the most: HTTP. The header of an HTTP response ends with an empty line. And it usually contains the content length of the body of the response.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thx for fast answer. now i see i mate mistake. it's not bufferedReader i must close but I closed PrintWriter. – Ania.K Dec 30 '15 at 21:17
  • @Ania.K so don't close the PrintWriter, just flush it after sending a terminating string. ideally you would use the same wrapper for the life of the socket connection. – Peter Lawrey Dec 30 '15 at 23:59
  • if i just flush doesn't work. it's blocking. – Ania.K Dec 31 '15 at 09:48