TCP Server 只接收一条消息

Posted

技术标签:

【中文标题】TCP Server 只接收一条消息【英文标题】:TCP Server only receives one message 【发布时间】:2015-08-19 08:38:12 【问题描述】:

我正在尝试创建一个简单的 TCP 服务器和客户端。我希望客户端能够通过只打开一次套接字来发送多条消息。我看过类似的问题 here、here 和 here,但它们并没有多大用处。

我的代码如下:

SampleServerTCP.java

public class SampleServerTCP 
    private static final int DEFAULT_PORT_NUMBER = 39277;

    public static void main(String[] args) throws IOException 
        ServerSocket defaultSocket = new ServerSocket(DEFAULT_PORT_NUMBER);

        System.out.println("Listening on port: " + DEFAULT_PORT_NUMBER);
        while (true)
            Socket connectionSocket = defaultSocket.accept();
            BufferedReader fromClient= new BufferedReader(new     InputStreamReader(connectionSocket.getInputStream()));
            String msg = fromClient.readLine();
            System.out.println("Recieved: " + msg);
        
    

TCPClientTest.java

public class TCPClientTest 

    public static void main(String args[]) throws UnknownHostException, IOException, InterruptedException
        Socket clientSocket = new Socket("localhost", 39277); 
        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

        int c = 0;
        while(c<10)
            outToServer.writeBytes(c + "\n");
            outToServer.flush();
            c++;
            Thread.sleep(500);
        
        clientSocket.close();
    

我得到的唯一输出是:

Listening on port: 39277
Recieved: 0

我哪里错了?

【问题讨论】:

您的服务器只读取一条消息。你为什么感到惊讶? 【参考方案1】:

你的问题在这里:

ServerSocket defaultSocket = new ServerSocket(DEFAULT_PORT_NUMBER);

    System.out.println("Listening on port: " + DEFAULT_PORT_NUMBER);
    while (true)
        Socket connectionSocket = defaultSocket.accept();
        BufferedReader fromClient= new BufferedReader(new     InputStreamReader(connectionSocket.getInputStream()));
        String msg = fromClient.readLine();
        System.out.println("Recieved: " + msg);
    

您正在打开套接字,只读取一行,然后您正在等待下一个套接字。

相反,您应该在 while 循环之外执行 Socket connectionSocket = defaultSocket.accept();,并在循环中从该套接字读取,如下所示:

System.out.println("Listening on port: " + DEFAULT_PORT_NUMBER);
Socket connectionSocket = defaultSocket.accept();
BufferedReader fromClient= new BufferedReader(new     InputStreamReader(connectionSocket.getInputStream()));
String msg = "";
while ((msg = fromClient.readLine()) != null)    
    System.out.println("Recieved: " + msg);

【讨论】:

readLine() 返回 null 时,您必须停止读取并关闭套接字。并且客户端 I/O 应该发生在一个单独的线程中,以便服务器可以同时为多个客户端提供服务。 谢谢。这解决了我的问题。但是,现在一旦客户端完成发送数据,并且套接字和 DataOutputStream 已关闭,服务器将打印“Recieved: null”,直到它停止。有没有办法检查客户端是否完成?最好不要通过 if(msg == null),是否有内置方法可以使用? @RichardJones 标准方式是String msg = ""; while((msg = fromClient.readLine()) != null) @Kayaman:谢谢,我将编辑我的答案以包含此内容。 EJP,你是对的,但 OP 问题根本不涉及多线程。 @Alex 这只是我用这段代码指出的两个灾难性问题之一。另一个导致了 OP 在上面的 cmets 中抱怨的无限循环。你已经解决了它,但没有承认任何人。【参考方案2】:

如下更改您的服务器端代码

公共类 SampleServerTCP 私有静态最终 int DEFAULT_PORT_NUMBER = 39277;

public static void main(String[] args) throws IOException 
    ServerSocket defaultSocket = new ServerSocket(DEFAULT_PORT_NUMBER);

    System.out.println("Listening on port: " + DEFAULT_PORT_NUMBER);
     Socket connectionSocket = defaultSocket.accept();
     BufferedReader fromClient= new BufferedReader(new     InputStreamReader(connectionSocket.getInputStream()));
     String msg = fromClient.readLine();;
    while (msg!=null)



        System.out.println("Received: " + msg);
        msg = fromClient.readLine();
    

【讨论】:

I 在 E 之前,C 之后除外。

以上是关于TCP Server 只接收一条消息的主要内容,如果未能解决你的问题,请参考以下文章

python 网络编程-03 粘包问题及处理

单线程下TCP循环等待接收客户端消息

Websocket4Net 只接收第一条消息的回复

C# TCP 客户端发送但不接收消息

tcp连接时,BROKEN PIPE错误的原因以及解决方法

JACK XMPP 守护进程发送和接收消息