Swoole

swoole

swoole Tcp和Udp区别 Tcp粘包问题


TCP(Transmission Control Protocol传输控制协议):

是一 种面向连接的、可靠的、基于字节流的传输层通信协议,使用三次握手协议建立连接、四次挥手断开连接。面向连接意味着两个使用TCP的应用(通常是一个客户端和一 个服务器)在彼此交换数据包之前必须先建立一一个TCP连接。在一一个TCP连接中,仅有两方进行彼此通信,广播和多播不能用TCP。TCP协议的作用是,保证数据通信的完整性和可靠性,防止丢包。TCP把连接作为最基本的对象,每-条TCP连接都有两个端点, 这种端点我们叫作套接字(socket),端口号拼接到IP地址即构成了套接字

UDP(User Datagram Protocol用户数据报协议):

是OSI(Open System Interconnection开放式系统互联)参考模型中- -种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。

1、TCP提供的是面向连接的、可靠的数据流传输; UDP提供的是非面向连接的、不可靠的数据流传输。TCP提供可靠的服务,通过TCP连接传送的数据,无差错、不丢失、不重复,按序到达; UDP尽最大努力交付,即不保证可靠交付。

2、TCP面向字节流; UDP面向报文。

3、TCP连接只能是点到点的; UDP支持-对一、一对多 多对一和多对多的交互通信。

4、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。

Tcp连接-三次握手

第一次握手:客户端发送网络包,服务端收到了。 这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次握手:服务端发包,客户端收到了。 这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。

第三次握手:客户端发包,服务端收到了。 这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也

swoole

swoole

Tcp连接-四次挥手

当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,"你发的FIN报文我收到了"。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。


swoole

swoole


Tcp粘包问题

tcp在发送数据的时候因为存在数据缓存的关系,对于数据在发送的时候在 短时间内 如果连续发送很多小的数据的时候就会有可能一次性一起发送,还有就是对于大的数据就会分开连续发送多次

解决方案:

1.特殊字符

根据客户端与服务端相互约定的特殊的符号,对接收的数据进行分割处理

2.固定包头+包体协议(主流)

通过与在数据传输之后会在tcp的数据包中携带上数据的长度,然后呢服务端就可以根据这个长度,对于数据进行截取


//设置包头
$server->set(array(
	'open_length_check' => true, 
	'package_max_length' => 81920, 
	'package_length_type' => 'N’,
	'package_length_offset' => 8, 
	'package_body_offset' => 16, 
));

// client 通过pack进行组包
for ($i=0; $i < 10; $i++) {
    // 组包
    // msg protocol
    // | ---- dataLen ---- | data |
    // | - fixed 2bytes  - |
    $context = "123";
    $len = pack("n", strlen($context));
    var_dump($len);

    $send = $len . $context;
    // var_dump($send);
    $client->send($send);
}

// server
//监听数据接收事件
$serv->on('Receive', function ($serv, $fd, $from_id, $data){
    var_dump($data);
    $fooLen = unpack("n", substr($data, $count, 2))[1];
    var_dump($fooLen);
    $foo = substr($data, $count + 2, $fooLen);
    var_dump($foo);
    $serv->send($fd, "Server: ");
});


(30)
分享:

本文由:xiaoshu168.com 作者:xiaoshu发表,转载请注明来源!

标签:

相关阅读