繁体   English   中英

通过 TCP 同时发送两个数据包时,一个丢失

[英]When sending two packets at once over TCP one is lost

我用Java作为服务端,PHP作为客户端,所以连接服务端后,我做socket_set_nonblock(这样socket_read时流不停止),然后通过while()我接受包(socket_read),但是麻烦也就是说,如果您一次发送两个包裹,第二个就会消失。

// socket class
public function __construct(int $port) {
    if(!($this->socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP)))
        var_dump('Ошибка при создании сокета: ' . socket_strerror(socket_last_error()) . PHP_EOL);
    if (!@socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, 1))
        var_dump('Не могу установить опцию на сокете: ' . socket_strerror(socket_last_error()) . PHP_EOL);
    if(!@socket_bind($this->socket, '127.0.0.1', $port))
        var_dump('Не удалось привязать адрес: ' . socket_strerror(socket_last_error()) . PHP_EOL);
}

public function connect(string $address, int $port): bool {
        if(($result = @socket_connect($this->socket, $address, $port)))
            if(!socket_set_nonblock($this->socket))
                var_dump('Не могу установить опцию: [nonblock] на сокете: ' . socket_strerror(socket_last_error()) . PHP_EOL);
        return $result;
    }

public function readData(): string {
    return socket_read($this->socket, ClientConst::MTU_SIZE);
}

// main class
public function main() {
    while(true) {
        if(($rawPacket = $this->primarySocket->readData()) !== '') {
            //todo: 
        }
    }
}

TCP 没有消息。 TCP 发送一个 stream 字节。 不能保证一个“发送”会在另一端导致一个“接收”。 可能是接收调用从两个发送中读取数据; 可能是两个接收调用,每个调用只读取一次发送的部分数据。

如果您想要消息边界,则需要提供它们。 有两种常见的技术:在每条消息前面加上一个长度,然后读取那么多字节; 或使用分隔符(例如 \n)并读取到分隔符。

暂无
暂无

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

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