UNIX网络编程

TCP三路握手步骤:
前提:服务器必须准备好接受外来的连接,这通过调用socket、bind和listen函数来完成,称为被动打开。
1.客户通过调用connet进行主动打开。这引起客户TCP发送一个SYN分节(表示同步),它告诉服务器客户将在(待建立的)连接中发送的数据的初始序列号。一般情况下SYN不携带数据,它只含有一个IP头部、一个TCP头部及可能有的TCP选项。
2.服务器必须确认客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器以单个分节向客户发送SYN和对客户SYN的ACK。
3.客户必须确认服务器的SYN。
每一个SYN的ACK中确认号都是相应的初始序列号加1,每一个FIN的ACK中的确认号为FIN序列号加1。

关闭时状态切换:
1.客户主动关闭,进入FIN_WAIT_1状态,发送FIN包,等待应答。
2.服务端接收到FIN包,进入CLOSE_WAIT状态,应答来自客户的FIN。
3.客户接收到服务器端的FIN应答包,进入FIN_WAIT_2状态。
4.服务端应用层调用close函数,发送FIN包。
5.客户接收到服务端的FIN包,进入TIME_WAIT状态,并发送最后一包,针对服务端FIN包的ACK。
6.服务端接受到ACK,正确终止此TCP连接。
TIME_WAIT状态:
主动执行关闭的那端将进入此状态,此状态持续2MSL时长。
此状态必须存在的两个理由:
1.实现终止TCP全双工连接的可靠性。(如果最后一包ACK丢失,被动关闭端将重发FIN包,主动关闭端必须维护之前的状态,以应答此FIN包)
2.允许老的重复分节在网络中消逝。

一个互联网TCP连接的唯一标识:套接口对,即本地IP、本地端口号、远程IP、远程端口号。
如果服务器主机崩溃,要等到客户向该服务器发送数据时才能检测到。
close将描述字的访问计数减1,当此计数为0时才真正关闭套接口。而shutdown可以激发TCP的正常连接终止序列,而不管访问计数。

使用select时:
1.如果对方TCP发送数据,套接口就变为可读,怯read返回大于0的值.
2.如果对方TCP发送一个FIN(对方进程正常终止),套接口变为可读,且read返回0
3.如果对方TCP发送一个RST(对方主机崩溃并重新启动),套接口变为可读,且read返回-1,errno描述了错误码


SO_BROADCAST
启用或禁止广播消息
SO_KEEPALIVE
如果两小时内,套接口的任意一个方向都没有数据交换,TCP会自动给对方发送一个心跳,对方如果收到必须响应
1.对方以期望的ACK响应,一切正常,如两小时内仍无数据交换,重复此过程
2.对方以RST响应,表示对方已崩溃并重启,待处理错误被设置为ECONNRESET,套接口被关闭
3.无响应,经过8次重发后扔无响应则错误被设置为ETIMEOUT,套接口被关闭.如果接收到一个ICMP错误作为某个心跳的响应,则返回相应的错误,套接口被关闭
SO_LINGER
struct linger
{
    int l_onoff;
    int l_linger;
};

l_onoff == 0:
选项关闭,l_linger的值被忽略,close立即返回
l_onoff != 0 && l_linger == 0:
当套接口关闭时TCP夭折连接.TCP将丢弃保留在套接口发送缓冲区的任何数据并发送一个RST给对方,而不是通常的FIN.避免了TCP的TIME_WAIT状态,不过不可取.
l_onoff != 0 && l_linger != 0:
当套接口关闭时,内核将拖延一段时间.如果在套接口发送缓冲区仍有数据,进程将处于睡眠状态,一直到所有数据都已经发送完并被对方确认,或者延迟时间到.如果套接口被设置为非阻塞的,它将不等待close的完成.如果在数据发送完并被确认前,延迟时间已经到时,close将返回EWOULDBLOCK错误,且套接口发送缓冲区的任何数据都丢失

设置SO_LINGER选项,只能告诉我们发送的数据已经由对方TCP确认,并不能告诉我们对方进程是否已经读取数据.
让客户知道服务器已经读取数据的一个方法是调用shutdown(SHUT_WR)而不是close

TCP_NODELAY
Nagle算法:如果给定连接上有待确认的数据,则直到现有数据被确认前,将不往连接上发送任何小分组.如果可能,TCP总是发送最大大小的分组,Nagle算发的目的是防止任何时刻连接上有多个待确认的小分组存在.
延滞算法:在接收到数据时,不立即发送ACK,而是由TCP等待一小段时间才发出ACK.

TCP端口是独立于UDP端口的,也就是说同一主机上两个分别为TCP和UDP的进程,允许绑定同一个端口,而不用设置SO_REUSEADDR选项。但两个TCP进程绑定同一个端口,则必须在调用bind前调用setsockopt设置SO_REUSEADDR选项。

UDP套接口可能产生异步错误,也就是说,sendto返回成功,但数据在真正发送的过程中有可能产生错误,只能在之后的某个时刻才能得到出错报告。

为套接口上的IO操作设置超时的三种方法:
1.调用alarm,在到达指定时间时产生SIGALRM信号,信号处理随不同实现变化,可能与进程中的其他已有的alarm调用冲突
2.使用select阻塞在等待IO上
3.使用新的SO_RECVTIMEO和SO_SNDTIMEO套接口选项,但不是所有实现都支持这两个选项

为connect设置超时:
1.调用异步connect,期望的错误为EINPROGRESS
2.使用select等待连接建立完成,当连接成功时,select返回可写,当出错时,返回既可读又可写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值