简体   繁体   English

如何使客户端套接字等待来自服务器套接字的数据

[英]how to make client socket wait for data from server socket

I have a simple client server program. 我有一个简单的客户端服务器程序。 Server can accept connection from multiple clients. 服务器可以接受多个客户端的连接。 Currently this is what is occurring in my client. 目前这是我的客户端发生的事情。
1) Type LIST in client. 1)在客户端输入LIST。 Server will send back all the files in current directory to client. 服务器将当前目录中的所有文件发送回客户端。 2) Type "Hello" in client. 2)在客户端输入“Hello”。 Server should send back "Hello". 服务器应该发回“你好”。 However, in the client the client reads blank. 但是,在客户端中,客户端读取空白。
I enter "QUIT" in client. 我在客户端输入“QUIT”。 I only see the Hello msg back from the server. 我只从服务器上看到Hello msg。
I cannot figure out why the client does not read the Hello msg after it is sent back by the Server. 我无法弄清楚为什么客户端在服务器发回Hello消息后不会读取它。

Client Code 客户代码

import java.net.*;   // Contains Socket classes
import java.io.*;    // Contains Input/Output classes
import java.nio.CharBuffer;

class ClntpracticeSandbox{

   public static void main(String argv[]){


   try{
//     
       Socket client=new Socket("localhost", 7777);
       System.out.println("Connected to server " + client.getInetAddress() 
             + ": " + client.getPort());
       System.out.println("local port is " + client.getLocalPort());

       BufferedReader kbreader;
       BufferedWriter writer;
       BufferedReader reader;

       kbreader = new BufferedReader(new InputStreamReader(System.in));
       writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
       reader = new BufferedReader(new InputStreamReader(client.getInputStream()));

       String data = "", datakb, line=null;

       do{
            System.out.print("Text to the server? ");
            datakb = kbreader.readLine();
            writer.write(datakb);
            writer.newLine();
            writer.flush();

            System.out.print("Received from the Server:  ");
            line = reader.readLine();
            while (line.equals("")==false){
                System.out.println(line);
                line = reader.readLine();
            }
       } while (datakb.trim().equals("QUIT")==false);          
       client.close();
       System.exit(0);

      }catch(Exception e){
          System.err.println("Exception: " + e.toString());
      }
   }
}

Server Code 服务器代码

import java.net.*;   // Contains Socket classes
import java.io.*;    // Contains Input/Output classes
import java.nio.file.*;

class SrvrpracticeSandbox{
    public static void main(String argv[]) throws IOException {
        ServerSocket s = new ServerSocket(7777);

        System.out.println("Server waiting for client on port " + s.getLocalPort());
        int count = 0;
        do {
            count = count + 1;
            Socket connected = s.accept();
            new clientThread(connected, count).start();
        } while (true);

    }
}

class clientThread extends Thread {

    Socket myclientSocket = null;
    int mycount;
    DataInputStream is = null;
    PrintStream os = null;


    public clientThread(Socket clientSocket, int count) {
        this.myclientSocket = clientSocket;
        this.mycount = count;
    }

    public void run() {
        try {

            System.out.println("New connection accepted " + myclientSocket.getInetAddress() + ": " + myclientSocket.getPort());

            BufferedReader reader;
            BufferedWriter writer;

            reader = new BufferedReader(new InputStreamReader(myclientSocket.getInputStream()));
            writer = new BufferedWriter(new OutputStreamWriter(myclientSocket.getOutputStream()));

            String data; 
            String testdirectory = "file1.txt\nfile2.txt\nfile3.txt";
            do{
                data = reader.readLine();
                System.out.println("Received from " +mycount + ":" + data);
                if (data.equals("LIST")) {
                    writer.write(mycount + "\n"+"150 - Transfer Initiated."+"\n"+
                            "DATA " +returnDirectoryList().getBytes().length + "\n" + 
                            returnDirectoryList() + "\r\n"); 
                } else {
                    writer.write("Server Echos to " + mycount + ":"+ data + "\n"+"This is a new line."+"\r\n"); 
                }                
                writer.newLine();
                writer.flush();

            }while (data.equals("QUIT") == false); 

            myclientSocket.close();
            System.exit(0);
        } catch (IOException ex) {
        }
    }
    private String returnDirectoryList()
    {
        String files = "";
        Path dir = Paths.get(".");
        try {
            DirectoryStream<Path> stream =
            Files.newDirectoryStream(dir);
            for (Path file: stream) {
                files = files + file.getFileName() +"\n";
            }
        } catch (IOException | DirectoryIteratorException x) {
            System.err.println("returnDirectoryList "+x.toString());
        }
        return files;        
    }
}

Sorry, I don't speak english, it's my first answer. 对不起,我不会说英语,这是我的第一个回答。 Try to wait the server response: 尝试等待服务器响应:

   do{
        System.out.print("Text to the server? ");
        datakb = kbreader.readLine();
        writer.write(datakb);
        writer.newLine();
        writer.flush();

        System.out.print("Received from the Server:  ");

        DataInputStream dataInputStream = new DataInputStream(client.getInputStream());

        int attempts = 0;
        while(dataInputStream.available() == 0 && attempts < 1000)
        {
            attempts++;
            Thread.sleep(10)
        }

        reader = new BufferedReader(dataInputStream);
        line = reader.readLine();

        while (line.equals("")==false){
            System.out.println(line);
            line = reader.readLine();
        }
   } while (datakb.trim().equals("QUIT")==false);          
   client.close();
   System.exit(0);

  }catch(Exception e){
      System.err.println("Exception: " + e.toString());
  }
  ...

The problem is because client is missing a empty line while reading LIST output from server. 问题是因为客户端在从服务器读取LIST输出时缺少空行。 Because of this after LIST command, Server and Client becoming out of sync. 因此,在LIST命令之后,服务器和客户端变得不同步。

In client code add these two lines end of do while loop. 在客户端代码中添加这两行do do while循环。 do { 做{

if (datakb.equals("LIST"))
        reader.readLine();
}while( ..)

It should have read the missed line and the problem should go away. 它本应该读取错过的线,问题应该消失。

You send all commands to the server and your server only looks for "LIST" as a special command, everything else will be handled by the "echo" part. 您将所有命令发送到服务器,并且您的服务器仅查找“LIST”作为特殊命令,其他所有命令将由“echo”部分处理。

if (data == null) {
  continue;
}
if (data.equals("LIST")) {
  writer.write(mycount + "\n" + "150 - Transfer Initiated." + "\n" +
    "DATA " + returnDirectoryList().getBytes().length + "\n" +
    returnDirectoryList() + "\r\n");
} else {
  writer.write("Server Echos to " + mycount + ":" + data + "\n" + "This is a new line." + "\r\n");
}

I tried with your code and the small changes above (since I got NPE) and the output looks like 我尝试使用你的代码和上面的小改动(因为我得到了NPE),输出看起来像

SERVERSIDE: 服务器端:

Server waiting for client on port 7777
New connection accepted /127.0.0.1: 52889
Received from 1:peter  
Received from 1:LIST

CLIENT SIDE: 客户端:

Connected to server localhost/127.0.0.1: 7777
local port is 52889
Text to the server? peter
Received from the Server:  Server Echos to 1:peter
This is a new line.
Text to the server? LIST
Received from the Server:  1
150 - Transfer Initiated.
DATA 6
Files
Text to the server? 

Isn't that the expected behaviour? 这不是预期的行为吗?

The statement System.exit(0); 语句System.exit(0); in clientThread 's run method is the problem. clientThread的run方法中就是问题所在。

It is causing the system to exit after serving one client. 它在服务一个客户端后导致系统退出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM