TTCP原理和实现
协议方式:
客户端先发送SessionMessage包括:
num:后续要发送的消息数目
len:每条消息的长度
struct SessionMessage
{
int32_t number;
int32_t length;
} __attribute__ ((__packed__));
客户端发送实际载荷:
length:该条消息的长度
char*data: 实际消息内容
struct PayloadMessage
{
int32_t length;
char data[0];
};
客户端发送消息数目到达num时,断开连接
echo协议设计
如果使用阻塞IO:
client:发送一段消息后,读取来自服务端的消息
server:边接收客户端数据,边往客户端转发,每次服务端接受4k,就立刻回传4k
存在问题:
如果发送数据过大,会填满内核缓冲区导致,服务端无法向客户端传输数据,同时客户端也无法向服务端发送数据。
常见协议设计方案:在连接时先传输header头,表明发送数据的大小,服务端接受完所有数据后,再向客户端回传。
TCP自连接
在同一台机器上
TCP端口同时打开功能
如:同一台机器上,客户端通过2677端口发送连接请求,连接到同一台机器上的同一端口,形成自连接。
TCP服务端不accept可以建立连接吗?
服务端:
socket执行bind绑定端口,执行listen方法,进入listen状态。
内核为处于listen状态的socket分配两个队列,『半连接队列』和『全连接队列』
每个listen Socket都有一个全连接和半连接队列
半连接队列(SYN队列):第一次握手时sock加入这个队列,队列中所有sock处于SYN_RECV状态
全连接队列(accept队列):收到三次握手的sock,从半连接队列中取出放入全连接队列,全连接队列中
sock处于ESTABLISHED状态。
执行accept():从全连接队列中取出一条连接
全连接队列和半连接队列
全连接队列:链表结构
半连接队列:hash表结构
全连接队列满了?
依赖tcp_abort_on_overflow参数设置。
0:丢弃第三个ACK报文,并超时重传,超过一定次数,将半连接队列中连接删除。
1:发送RST,断开连接。
半连接队列满了?
tcp_syncookies参数设置
1:收到第一次SYN时,生成cookies,这个cookies返回客户端,第三次
握手时带上cookies,验证,并将连接放入全连接队列
cookies:通过双方IP、端口、MSS实时计算放入TCP头的seq中。
如果第二次握手包丢失,不会触发重传,编解码消耗CPU