繁体   English   中英

Java TCP套接字无法正确接收

[英]Java tcp socket does not receive properly

嗨,让我直接解决这个问题。 客户端通过身份验证后,服务器会向该客户端发送一个大的JSON数据包

但是数据包以一种奇怪的方式返回,例如被拆分或出现以下示例:

JSON应该是:

Received: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,"ItemSlots":30}

通过时:

Received: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,
Received: "ItemSlots":30}

为什么要分割数据包或其他东西,如何解决客户端问题?

Java接收代码:

   private class ClientThread extends Thread {
        public void run() {
            try {
                while (selector.select() > 0) {
                    for (SelectionKey sk : selector.selectedKeys()) {

                        selector.selectedKeys().remove(sk);
                        if (sk.isReadable()) {

                            SocketChannel sc = (SocketChannel)sk.channel();
                            ByteBuffer buff = ByteBuffer.allocate(1024);
                            String content = "";

                            while (sc.read(buff) > 0) {
                                sc.read(buff);
                                buff.flip();
                                content += charset.decode(buff);
                                buff.clear();
                            }

                            System.out.println("Recieved: " + content);
                            sk.interestOps(SelectionKey.OP_READ);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

谢谢,祝你有美好的一天。

TCP协议不维护消息边界。 不能保证服务器发送的内容是客户端原样接收的,反之亦然。

如果服务器发送1000字节的数据,则客户端应用程序可以跨多个recv或单个recv接收相同的数据。 TCP不保证任何行为。 可能会发生“拆分”,这取决于应用程序来处理来自多个块的数据,将其合并到一个单元的应用程序数据中以进行进一步处理。 特别是对于大数据量,可以看到这一点。

看起来您有一个无阻塞的套接字通道,这意味着while (sc.read(buff) > 0) {循环因sc.read(buff)返回0而终止,因为仅发送了一部分数据至此,已经收到。

为什么要拆分数据包之类的东西?

数据很可能被拆分为两个或更多数据包。

以及我该如何解决呢?

继续填充缓冲区,直到服务器关闭套接字为止(在这种情况下, read应该返回-1而不是0)。 您需要为每个通道维护一个单独的缓冲区。 如果服务器在发送数据后没有关闭其末端,则需要以其他方式进行描述。 例如,您可以在JSON blob的前面加上大小标头。

嗨lemme直接解决了这个问题,所以我获得了一个大的JSON数据包,一旦客户端通过身份验证,服务器就会发送到该客户端

您的意思是您有一条很大的JSON 消息 数据包是网络协议用来交换信息的事物。

但是数据包以一种奇怪的方式返回,例如拆分或类似的例子:

除非您查看电线,否则您不会查看数据包。 您正在查看从TCP连接结束获得的字节数。

JSON应该是:

已接收:{“ UserID”:1,“ PlayerID”:2,“ EXP”:0,“ Lvl”:1,“ Coins”:0,“ ItemSlots”:30}

通过时:

已接收:{“ UserID”:1,“ PlayerID”:2,“ EXP”:0,“ Lvl”:1,“硬币”:0,已接收:“ ItemSlots”:30}

优秀的。 您得到了相同的字节。 现在创建一个JSON解析器,以弄清消息的结尾并对其进行解析。

为什么要拆分数据包之类的东西?

它将消息拆分为数据包,因为这就是TCP将消息发送到另一端的方式。 TCP不是消息协议,它不知道或不在乎应用程序认为什么是消息,这就是应用程序的工作。

以及我该如何解决呢?

编写JSON解析器以找出消息的结尾。 您尚未实现任何代码来通过TCP接收JSON,因此直到您这样做才起作用。

TL; DR:如果需要应用程序级消息协议,则需要实现一个。 TCP不是一个。

暂无
暂无

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

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