Socket/TCP编程

socket可以利用name和address建立的一个链接的端点(endpoint).

socket编程展示了如何用Socket API在远程和本地进程之间建立链接.

Tcp是基于流(Stream)的通讯协议,由于是Stream的,像水流一样,整体不可分割,所以整个链接从建立到结束只不存在任何中间标记的,需要利用一些自定义的约定或者约束来进行及交互的解析.

策略一:固定长度

发送端Client每次发送固定长度byte的请求,接收端每次只要读取固定长度的内容就可以进行解析.

例子协议1:
假设有个物联网协议,固定交互长度为2byte+1bit:
0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0
前2个byte标记是设备,共计2^8 = 65536个设备
后1个byte标记设备状态,共计256个状态(开或者关或者其他)

策略二:不定长度

每次交互的长度不固定,那么可以利用Client在发送的第一次内容上标记当前的请求长度.

例子协议2:
0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 ...
第一个u32(Integer)指定后续内容的长度, 那么后续内容长度可为(2^32 = 4,294,967,296 bytes ≈ 4GB)

策略三:固定标记

以特殊的标记来分割整个stream,常见的有\n或者\r\n

CR = Carriage Return,回车符号(\r,十六进制 ascii 码为0x0D,十进制 ascii 码为 13),用于将鼠标移动到行首,并不前进至下一行

LF = Line Feed,换行符号( \n, 十六进制 ascii 码为 0x0A,十进制 ascii 码为 10)

例子协议3(\n标记):
0 0 0 0 0 0 0 0 | 0 0 0 0 1 0 1 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 1 0 1 0 |
解析结果为: 1 bytes + LF + 2 bytes + LF

混合

在一些具体的协议设计上也可以混合其中的几种方式,其实不定长度的第一个长度数据标记也是固定长度的一种想法