1

一直试图解决这个问题大约 5 个小时,但似乎看不到它,虽然所有步骤都已完成发送数据,但我只能接收到服务器的消息,但不能从服务器到客户端。我正处于构建/学习如何在命令行中执行聊天客户端程序的早期阶段。以下是服务器代码:

CServer 类:

public class CServer {

private static int port=2008, maxConnections=0;
private static String shutDownServer = "no";

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


    ServerSocket listen = new ServerSocket(port);
    Socket server;

    while(shutDownServer.equalsIgnoreCase("no")){

        doComm connection;

        System.out.println("\nWaiting for clients to connect...");

        server = listen.accept(); // accept incomming connections from client
        System.out.println("Client connected. Location: " + server.getInetAddress().getHostName());
        connection = new doComm(server);

        Thread thread = new Thread(connection);
        thread.start();
    }



}

public void shutDownServer(String command){

    this.shutDownServer = command;
}
}

现在处理线程中每个客户端的 doComm 类:

public class doComm implements Runnable{

Socket server;
private String clientData;

  public doComm(Socket server){

      this.server = server;
  } 

  public void run(){

     try {

      BufferedReader fromClient = new BufferedReader(new InputStreamReader(server.getInputStream()));
      DataOutputStream toClient = new DataOutputStream(server.getOutputStream());

      clientData = fromClient.readLine();
         System.out.println("Client sent: "+clientData);

((问题 -imo- 可能是这句话:))

      toClient.writeBytes("Recieved your sentence '"+clientData+"' and more to come :)!");

    //server.close();

  } catch (IOException e) {
    System.out.println("IOException on socket listen: " + e);
    e.printStackTrace();
  }

  }
}

现在客户端类 CClient:

    public class CClient {

    static String address = "localhost";

static int port = 4444;
static Socket echoSocket;

     public CClient(int port, String addr){

         changePort(port);
         changeAddr(addr);
     }

     public static void main(String[] args) throws IOException, UnknownHostException{

         Scanner scan = new Scanner(System.in);

         System.out.println("Please enter the port to connect to: ");
         int temp_port = Integer.parseInt(scan.nextLine());
         System.out.println("Please enter the address of server: ");
         System.out.flush();
         String temp_addr = scan.nextLine();

         CClient client = new CClient(temp_port,temp_addr);

            PrintWriter out = null;
            BufferedReader in = null;

         try{
             System.out.flush();
             echoSocket =  new Socket(address,port);
             out = new PrintWriter(echoSocket.getOutputStream(), true);
             in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
         }
         catch(IOException e){

             System.err.println("IOException error: " + e.getStackTrace());
         }

         BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
    String userInput;

    while ((userInput = stdIn.readLine()) != null) {

        out.println(userInput);
            System.out.println("thingy prints right after this...");

((或这里:))

System.out.println("echo: " + in.readLine());
}
 }

 public void changePort(int port){

     this.port=port;
 }

 public void changeAddr(String addr){

     this.address=addr;
 }
}
4

1 回答 1

3
  clientData = fromClient.readLine();

  toClient.writeBytes("Recieved your sentence '"+clientData+"' and more to come :)!");

这是一个非常常见的问题,其根本原因是未能记录指定用于通信的协议。在这里,您正在接收但正在发送字节。如果您有一个协议文档,它会指定交换行或交换任意字节单位。这将表明这些代码行之一是错误的,您可以修复它。但是如果没有协议规范,你甚至无法判断哪一方是错误的。

请从多年的痛苦教训中吸取我的建议——在实施之前记录协议。然后,如果它不起作用,您可以按照以下三个步骤进行操作:

  1. 客户是否遵循记录在案的协议?如果没有,它就坏了。

  2. 服务器是否遵循记录的协议?如果没有,它就坏了。

  3. 协议规范被破坏。

在这种情况下,协议规范将记录什么构成您的协议的“消息”。然后,每一方都有责任发送完整的消息并在接收时找到这些消息边界。但是,在您的情况下,一段代码需要一个行终止符来标记消息边界,而另一端不发送一个。

发件人省略消息边界是错误的吗?收货人坚持要收一份有错吗?没有人知道,因为没有说明什么是正确的做法。

于 2013-02-05T19:37:20.990 回答