【问题标题】:how to make client socket wait for data from server socket如何使客户端套接字等待来自服务器套接字的数据
【发布时间】:2018-07-11 07:47:07
【问题描述】:

我有一个简单的客户端服务器程序。服务器可以接受来自多个客户端的连接。目前,这就是我的客户正在发生的事情。
1) 在客户端中输入 LIST。服务器会将当前目录中的所有文件发送回客户端。 2)在客户端输入“你好”。服务器应该发回“Hello”。但是,在客户端中,客户端读取空白。
我在客户端输入“QUIT”。我只看到从服务器返回的 Hello msg。
我无法弄清楚为什么客户端在服务器发回之后没有读取 Hello msg。

客户代码

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());
      }
   }
}

服务器代码

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;        
    }
}

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    对不起,我不会说英语,这是我的第一个答案。尝试等待服务器响应:

       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());
      }
      ...
    

    【讨论】:

      【解决方案2】:

      问题是因为客户端在从服务器读取 LIST 输出时缺少一个空行。因此,在 LIST 命令之后,服务器和客户端变得不同步。

      在客户端代码中将这两行添加到 do while 循环的末尾。 做{

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

      它应该已经读取了丢失的行并且问题应该消失了。

      【讨论】:

        【解决方案3】:

        您将所有命令发送到服务器,并且您的服务器只查找“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");
        }
        

        我尝试了你的代码和上面的小改动(因为我得到了 NPE),输出看起来像

        服务器端:

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

        客户端:

        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? 
        

        这不是预期的行为吗?

        【讨论】:

        • 你好,彼得我希望服务器继续处理来自客户端的请求,直到客户端发送 QUIT。当客户端从服务器读取请求时,主要问题出在客户端。对于从客户端发送的除 QUIT 以外的请求,客户端从服务器读取“”。
        【解决方案4】:

        clientThread 的 run 方法中的声明 System.exit(0); 是问题所在。

        服务一个客户后导致系统退出。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-12-15
          • 1970-01-01
          • 2018-09-02
          • 2014-03-10
          • 2017-12-10
          • 2011-11-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多