高并发服务器 ----select

文章详细介绍了TCP连接中的三次握手和四次挥手过程,以及如何实现端口复用。同时,讨论了多路复用技术,特别是使用select函数进行文件描述符的监控,包括其参数和返回值的解释。在示例代码中,展示了如何使用C语言实现一个简单的服务器程序,监听连接并处理客户端数据。
摘要由CSDN通过智能技术生成

TCP状态转换

三次握手完成

SYN_SENT:connet();
LISTEN:

四次挥手过程:

主动关闭方:
FIN_WAIT_1
FIN_WAIT_2
TIME_WAIT
被动关闭方:
CLOSE_WAIT:
LASK_ACK:

在这里插入图片描述

端口复用

半关闭

多路复用技术 select函数介绍

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set exceptfds, struct timevaltimeout);
nfds:文件描述符号
readfds:读事件
writefds:
–写时间
exceptfds:–输入输出参数, 表示异常事件
timeout:–超时时间
-----NULL:永久阻塞
-----0:不阻塞 不管有没有时间发生 都立刻返回
----- >0:阻塞时长 没超过时长一直阻塞 在时长内有事件发生就立刻返回 超过时长就立刻返回

return:<0失败 ------->0发生事件的文件描述符有多少个

   void FD_CLR(int fd, fd_set *set);
   说明:从Set中清楚fd
   int  FD_ISSET(int fd, fd_set *set);
   说明:fd是否在set里面
   void FD_SET(int fd, fd_set *set);
   说明:将fd添加到集合当中
   void FD_ZERO(fd_set *set);
   说明:清空set
#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#define SERV_PORT 6666
int main(int argc, char *argv[])
{
	CFLAGS = -lpthread -m32 -Wall -g  makefile 5
	int listenfd,connectfd;
	char buf[BUFSIZ];
	int n = 0;
	socklen_t clie_addr_len;//传出地址的大小
	listenfd = socket(AF_INET,SOCK_STREAM,0);
	//端口复用setsockopt

	int opt = 1;
	setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
	//定义地址
	struct sockaddr_in serv_addr,clie_addr;

	//初始化
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port = htons(SERV_PORT);
	bind(listenfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
	listen(listenfd,128);

	//两个集合  一个监听  一个备份
	fd_set rset,allset;
	//清零第2个集合  将lfd添加到监听集合
	int ret,maxfd = 0;
	maxfd = listenfd;

	FD_ZERO(&allset);
	FD_SET(listenfd,&allset);
	while(1)
	{
		rset = allset;
		ret = select(maxfd+1,&rset,NULL,NULL,NULL);
		if (ret<0)
		{
			perror("select");
		}
		if(FD_ISSET(listenfd,&rset))
		{
			connectfd = accept(listenfd,(struct sockaddr*)(&clie_addr),&clie_addr_len);
			
			FD_SET(connectfd,&allset);
			if (maxfd<connectfd)
			{
				maxfd = connectfd;
			}
			if (ret == 1)
			{
				continue;
			}
		}
		for (int i = listenfd; i < maxfd+1 ; ++i)
			{
				if(FD_ISSET(i,&rset))
			{
				n = read(i,buf,sizeof(buf));
				if (n==0)
				{
					close(i);
					FD_CLR(i,&allset);
				}
				for (int j = 0; j < n; ++j)
				{
					buf[j] = toupper(buf[j]);	
				}
				write(i,buf,n);
				write(STDOUT_FILENO,buf,n);
			}
		}
	}

	//调用select函数
	// 每次循环重新调用select函数
	// 添加


	//返回值大于0;有请求 ;   
	//调用connect连接

	close(listenfd);

	return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值