一、send/recv
read的替代函数是recv,write的替代函数是send;区别是recv和send多了一个输入参数flags,flags = 0;两种函数一样。
二、TCP状态转换
循环:起点就是终点。
(1)建立连接
客户端:起点(CLOSED)—>第一次握手(SYN_SEND)—>第二次握手(ESTABLISHED)
服务器端:起点(LISEN)–>SYN_RECV;
然后就是通信的过程。
(2)断开连接
客户端:ESTABLISHED—>第一次挥手(FIN_WAIT_1)—>第二次挥手(FIN_WAIT_2)
服务器端:CLOSE_WAIT
这是断开客服端向服务器端发送数据的单工通信的道路。
另一端相同过程,但是对象置换。
Q:如何去捕捉这些状态转化?
A:
①SYN_SENT和ESTABLISHED状态能捕捉,而SYN_RECV时间短暂,不容易捕捉到。
②FIN_WAIT_1
1、主动断开连接的一方,最后的状态为TIME_WAIT,不会直接关闭,会等待一段时间2MSL(MSL= 30秒),也就是等一分钟。为什么要等一分钟呢,而被动断开不用等呢?
A:因为被动断开最后收到ACK 会直接断开连接(其实是回收进程),因为被动断开最后需要接受ACK,但是当没有接手后需要重传,这个2MSL就是一种保护机制,保证被动断开能保证断开(保证进程被回收)。
2MSL:a.等待时长; b.主动关闭连接的一方,处于TIME_WAIT状态; c.有的地方:2分钟,一般时候30s(MSL)
2、半关闭
TCP通信双向连接,有一端关了,有一端没关。
A给B发送是FIN(A调用了close函数),但是B没有给A发FIN,B没有调用close,即A断开了与B的连接,B没有断开与A的连接。
特点:A不能给B发送数据,A可以接受到B的数据。B能给A发送数据。
函数:实现半关闭函数int shutdown(int sockfd,iint how);
3、查看网络相关状态信息
命令:netstat
原因是主动断开的一方会有一个等待时长,再回收进程,上图就是因为还在等待时间内,所以会报错。
4、端口复用
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname,
void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
复用的是用于监听的套接字文件描述符。