【问题标题】:Client doesn't receive message from Server - using select() call on server客户端没有收到来自服务器的消息 - 在服务器上使用 select() 调用
【发布时间】:2019-09-23 22:23:05
【问题描述】:

我的常规 TCP 客户端在常规 TCP 服务器上工作得很好,但不是 SelectServer,它基本上是一个使用 select() 调用非阻塞 IO 的 TCP 服务器:

class TCPClient { 

public static void main(String args[]) throws Exception 
{ 
    if (args.length != 2)
    {
        System.out.println("Usage: TCPClient <Server IP> <Server Port>");
        System.exit(1);
    }

    // Initialize a client socket connection to the server
    Socket clientSocket = new Socket(args[0], Integer.parseInt(args[1])); 

    // Initialize input and an output stream for the connection(s)
    DataOutputStream outBuffer = new DataOutputStream(clientSocket.getOutputStream()); 
    BufferedReader inBuffer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 

    // Initialize user input stream
    String line; 
    BufferedReader inFromUser = 
    new BufferedReader(new InputStreamReader(System.in)); 

    // Get user input and send to the server
    // Display the echo meesage from the server
    System.out.print("Please enter a message to be sent to the server ('logout' to terminate): ");
    line = inFromUser.readLine(); 
    while (!line.equals("logout") )
    {
        try{
        // Send to the server
        outBuffer.writeBytes(line + '\n'); 

        // Getting response from the server
        System.out.println("Bytes written.. waiting for response");
        line = inBuffer.readLine();
        System.out.println("Message received!");
        System.out.println("Server: " + line);
        }catch(SocketException e){}
        System.out.print("Please enter a message to be sent to the server ('logout' to terminate): ");
        line = inFromUser.readLine(); 
    }


    // Close the socket
    clientSocket.close();           
} 

}

这个 TCP 客户端卡在line = inBuffer.readLine(); 线上,因为它没有收到任何消息。

我的服务器使用 select() 调用非阻塞 IO:

    public class SelectServer {

   public static void main(String[] args)throws Exception {
      //InetAddress host = InetAddress.getByName("some host or ip"); //Enter some host or ip here 

      Selector selector = Selector.open();

      ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
      serverSocketChannel.configureBlocking(false);
      InetSocketAddress isa1 = new InetSocketAddress(9000);
      serverSocketChannel.socket().bind(isa1);
      serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);


      while (true) {

         if (selector.select(500) < 0) //500miliseconds
                {
                    System.out.println("select() failed");
                    System.exit(1);
                }

         Set selectedKeys = selector.selectedKeys();
         Iterator iterator = selectedKeys.iterator();

         while (iterator.hasNext()) {

            SelectionKey key = (SelectionKey) iterator.next();
            iterator.remove();

            if (key.isAcceptable()) {
               //System.out.println("Acceptable");
               SocketChannel sc = serverSocketChannel.accept();
               sc.configureBlocking(false);
               sc.register(selector, SelectionKey.OP_READ);
               System.out.println("Connection Accepted: " + sc.getLocalAddress() + "\n");
            }

            if (key.isReadable()) {
                //System.out.println("Readable");
               SocketChannel sc = (SocketChannel) key.channel();
               ByteBuffer bb = ByteBuffer.allocate(1024);
               int bytesRead = sc.read(bb);
               String result = new String(bb.array()).trim();
               System.out.println("Message received: " + result + " ,Message length= " + result.length());

               if (result.equals("logout")) {
                  sc.close();
                  System.out.println("Connection closed...");
                  System.out.println("Server will keep running. " +"Try running another client to " + "re-establish connection");
               }

               sc.register(selector, SelectionKey.OP_WRITE);

            }  
            if (key.isWritable()){

                System.out.println("Writable");                   

                SocketChannel sc = (SocketChannel) key.channel();
                ByteBuffer bb = ByteBuffer.wrap("text".getBytes());

                int bytesWritten = sc.write(bb);
                System.out.println(bytesWritten);  //Prints 4 

                bb.rewind();

                sc.register(selector, SelectionKey.OP_READ);

            }

         }
      }
   }
}

int bytesWritten = sc.write(bb); 行中,写入的字节数打印为 4。因此字节已发送..但未收到。客户卡在我上面提供的那一行。

如果我不“弄乱”ByteBuffer,而只是回显消息,它就会完美发送。但是,如果我真的尝试将自定义消息输入到 ByteBuffer 中,客户端不会收到它。

为什么会这样?

【问题讨论】:

    标签: java sockets select network-programming serversocket


    【解决方案1】:

    只需在末尾添加一个新行即可解决问题,例如“text\n”。不敢相信就这么简单。

    【讨论】:

      猜你喜欢
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-05
      相关资源
      最近更新 更多