socket网络编程

一、函数含义:
TCP
client:socket()、bind() 可选、connect()、recv()、send()、close
server:socket()、bind()、listen()、accept()、recv()、send()、close()

int socket(int domain, int type, int protocol);//创建一个文件描述符,tcp control block;
参数一:常用的AF_INET //ipv4协议簇
		     AF_INET6 //ipv6协议簇
参数二:SOCK_STREAM // 数据流 tcp
	   SOCK_DREAM //数据包 udp
参数三:为0时,会自动选择type类型对应的默认协议。
返回值:0表示成功 -1表示失败
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);//将addr指定的地址分配给文件描述符
参数一:socket描述符,通过socket函数创建。
参数二:struct sockaddr_in seraddr;
			  servaddr.sin_family = AF_INET;
			  servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 0.0.0.0 设置INADDR_ANY可以访问任意的eth0 eth1等网卡,也可以单独设置eth0或eth1 网卡地址进行通信,lo本地进行通信
			  servaddr.sin_port = htons(9999);//端口 short类型范围0-65535,系统使用0-1024,一般设置为1024-65535之间
参数三:参数二的sizeof大小
返回值:0表示成功 -1表示失败

int listen(int sockfd, int backlog);//监听客户端的连接,设置fd监听状态,创建半连接队列和全连接队列
参数一:socket描述符,通过socket函数创建。
参数二:全双工队列中最大连接数
返回值:0表示成功 -1表示失败

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);//从全连接队列中取出数据并分配新的fd,五元组与新fd进行绑定
参数一:socket描述符,通过socket函数创建。
参数二:用来接受返回客户端地址
参数三:参数二的sizeof大小
返回值:一个新的fd,用于客户端和服务器间通信

int send( SOCKET s, const char FAR *buf, int len, int flags );
参数一、socket描述符,通过accept函数创建。
参数二、发送的数据
参数三、发送的数据大小
返回值:表示写入到内核缓冲区大小

int recv( _In_ SOCKET s, _Out_ char *buf, _In_ int len, _In_ int flags);
参数一、socket描述符,通过accept函数创建。
参数二、读取的数据
参数三、需要读取的数据大小
返回值:从内核读缓冲区读取数据大小,为0接受到对端关闭(eof)

int close(int fd);//回收fd
参数:socket描述符,通过accept函数创建。
返回值:成功返回0,出错返回-1
	int sockfd = socket(AF_INET, SOCK_STREAM, 0); // io
	
	struct sockaddr_in servaddr;
	memset(&servaddr, 0, sizeof(struct sockaddr_in)); // 192.168.2.123
	servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 0.0.0.0
    servaddr.sin_port = htons(9999);

    if (-1 == bind(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr))) {
		printf("bind failed: %s", strerror(errno));
		return -1;
    }

    listen(sockfd, 2);	//最大连接个数是2+1
    getchar(); 

在这里插入图片描述
为什么最大个数是backlog+1个?

二、tcp状态迁移图
在这里插入图片描述
三次握手(客户端调用connect(),服务器调用listen()进入监听状态后)
在这里插入图片描述

四次挥手过程(客户端或服务器主动调用close)
在这里插入图片描述

1.tcp连接的生命周期,从什么时候开始?accept()
2.第三次握手数据包,如何从半连接队列查找匹配的节点?五元组 (源端口、目的端口、源IP、目的IP、protocol)
3.time_wait 主动关闭连接的一方
出现大量time_wait的原因?
客户端没有关闭, 频繁的短连接, 四次挥手之后超时

4.为什么要有2MSL(maxmum segment lifetime,最大报文生存时间)?
a.确保可靠关闭连接:在CLOSED状态之前进入TIME_WAIT状态可以确保双方都能完全接收并处理所有数据包。
b.避免旧连接干扰:如果新建立的连接使用了相同的源IP地址和端口号,而旧连接还处于网络中,在TIME_WAIT期间会阻止重复的连接请求。
c.处理网络延迟和重传:在TIME_WAIT状态期间,可以处理来自对方发送的延迟到达或重传的数据包,以避免数据丢失。
需要注意的是,如果服务器频繁出现大量处于TIME_WAIT状态的TCP连接,可能会导致资源浪费。这时可以通过调整操作系统参数来缩短TIME_WAIT持续时间或增加可用端口范围来解决问题,服务器不作为主动断开连接的一方。

如果客户端大量断网(心跳检测期间都没连接上),是不是需要服务器主动断开连接,进行四次挥手,会不会有大量time_wait?
5.close_wait 被动关闭连接的一方
大量的close_wait出现的原因及解决方案?
未正确调用close接口,如recv返回0,先调用close接口关闭fd,业务等数据处理可以使用异步方式单独处理
tpc作为全双工通信,shudown关闭其中一路。不推荐使用shudown,关闭使用close。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值