网络通信协议设计

为什么需要通信协议

TCP协议在底层机制上解决了UDP协议的顺序和丢包重传问题。但相比UDP又带来了新的问题,TCP协议是流式的,数据包没有边界。应用程序使用TCP通信就会面临这些难题。

因为TCP通信是流式的,在接收1个大数据包时,可能会被拆分成多个数据包发送。多次Send底层也可能会合并成一次进行发送。这里就需要2个操作来解决:

  • 分包:Server收到了多个数据包,需要拆分数据包
  • 合包:Server收到的数据只是包的一部分,需要缓存数据,合并成完整的包

所以TCP网络通信时需要设定通信协议。常见的TCP网络通信协议有HTTPHTTPSFTPSMTPPOP3IMAPSSHRedisMemcacheMySQL

如果要设计一个通用协议的Server,那么就要按照通用协议的标准去处理网络数据。除了通用协议外还可以自定义协议。Swoole支持了2种类型的自定义网络通信协议。

EOF结束符协议

EOF协议处理的原理是每个数据包结尾加一串特殊字符表示包已结束。如memcacheftpstmp都使用\r\n作为结束符。发送数据时只需要在包末尾增加\r\n即可。使用EOF协议处理,一定要确保数据包中间不会出现EOF,否则会造成分包错误。

swoole_serverswoole_client的代码中只需要设置2个参数就可以使用EOF协议处理。

$server->set(array(
    'open_eof_split' => true,
    'package_eof' => "\r\n",
));
$client->set(array(
    'open_eof_split' => true,
    'package_eof' => "\r\n",
));

固定包头+包体协议

固定包头的协议非常通用,在BAT的服务器程序中经常能看到。这种协议的特点是一个数据包总是由包头+包体2部分组成。包头由一个字段指定了包体或整个包的长度,长度一般是使用2字节/4字节整数来表示。服务器收到包头后,可以根据长度值来精确控制需要再接收多少数据就是完整的数据包。Swoole的配置可以很好的支持这种协议,可以灵活地设置4项参数应对所有情况。

Swoole的Server和异步Client都是在onReceive回调函数中处理数据包,当设置了协议处理后,只有收到一个完整数据包时才会触发onReceive事件。同步客户端在设置了协议处理后,调用 $client->recv() 不再需要传入长度,recv函数在收到完整数据包或发生错误后返回。

$server->set(array(
    'open_length_check' => true,
    'package_max_length' => 81920,
    'package_length_type' => 'n', //see php pack()
    'package_length_offset' => 0,
    'package_body_offset' => 2,
));


  • CodingMan

    可以处理mqtt这种协议吗?

  • 蛟十五

    header+length+header+data = 固定包头协议

  • 蛟十五

    data+eof+data+eof = EOF结束符协议

  • 猪肉炖粉条

    websocket协议基于第二种方式实现,http是第一种(报头)和第二种(content-type)的混合使用

  • 挨踢-GO

    计算机网络按地理范围划分为局域网,城域网,广域网;

    局域网提高数据传输速率 10mbps-10gbps,低误码率的高质量传输环境

    局域网按介质访问控制方法角度分为共享介质式局域网和交换式局域网

    局域网按传输介质类型角度分为有线介质局域网和无线介质

    局域网早期的计算机网络主要是广域网,分为主计算机与终端(负责数据处理)和通信处理设备与通信电路(负责数据通信处理)

    计算机网络从逻辑功能上分为资源子网和通信子网

  • 挨踢-GO

    总结一下UDP和TCP的区别

    -使用UDP时,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。

    -对于TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中多了一个连接建立的时间。

    -使用UDP传输数据时时有大小限制的,每个被传输的数据报必须限定在64KB之内

    -TCP没有这方面的限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。

    -UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。

    -TCP是一个可靠的协议,它确保接收方完全的获取发送方所发送的全部数据。

    -TCP是在网络通信中具有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠的传输。

    -UDP操作简单,仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序

  • 挨踢-GO

    总结一下UDP和TCP的区别

    -使用UDP时,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。

    -对于TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中多了一个连接建立的时间。

    -使用UDP传输数据时时有大小限制的,每个被传输的数据报必须限定在64KB之内

    -TCP没有这方面的限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。

    -UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。

    -TCP是一个可靠的协议,它确保接收方完全的获取发送方所发送的全部数据。

    -TCP是在网络通信中具有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠的传输。

    -UDP操作简单,仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序

  • 挨踢-GO

    总结一下UDP和TCP的区别

    -使用UDP时,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。

    -对于TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中多了一个连接建立的时间。

    -使用UDP传输数据时时有大小限制的,每个被传输的数据报必须限定在64KB之内

    -TCP没有这方面的限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。

    -UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。

    -TCP是一个可靠的协议,它确保接收方完全的获取发送方所发送的全部数据。

    -TCP是在网络通信中具有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠的传输。

    -UDP操作简单,仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序