socket编程使用poll替换select

本文探讨了在处理并发socket连接时,如何利用poll函数替代传统的select方法,重点介绍了poll的优势,即它不受FD_SETSIZE限制,能够更好地处理大量并发连接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

poll函数在处理并发时, 无FD_SETSIZE限制

//服务器端
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>//使用signal函数
#include <sys/wait.h>//使用wait函数
#include <poll.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#define ERR_EXIT(m) \
	do \
	{ \
		perror(m);	\
		exit(EXIT_FAILURE);\
	}while(0)



//读确定大小的包
//ssize_t有符号数,size_t为无符号数
ssize_t readn(int fd, void *buf, size_t count)
{
	size_t nleft=count;//剩余字节数
	ssize_t nread;//已经接受的字节数
	char *bufp = (char*)buf;//

	while(nleft>0)
	{
		if((nread=read(fd, bufp, nleft))<0)
		{
			if(errno==EINTR)//信号中断
			{
				continue;
			}
			return -1;//否则出错
		}
		else if(nread==0)//表示对方关闭传送
		{
			return count-nleft;//返回已读字节数
		}
		bufp+=nread;//进行指针偏移
		nleft -= nread;
	} 
	return count;
}
ssize_t writen(int fd, const void *buf, size_t count)
{
	size_t nleft=count;//剩余字节数
	ssize_t nwritten;//已经写入的字节数
	char *bufp = (char*)buf;//

	while(nleft>0)
	{
		if((nwritten=write(fd, bufp, nleft))<0)
		{
			if(errno==EINTR)//信号中断
			{
				continue;
			}
			return -1;//否则出错
		}
		else if(nwritten==0)
		{
			continue;
		}
		bufp+=nwritten;//进行指针偏移
		nleft -= nwritten;
	} 
	return count;
}
ssize_t recv_peek(int sockfd, void *buf,size_t len)
{
	while(1)
	{
		//recv函数只用于套接口
		//recv函数读取后,不将数据在缓冲区清除
		int ret= recv(sockfd, buf, len, MSG_PEEK);
		if(ret == -1 && errno == EINTR)
			continue;
		return ret;
	}
}

ssize_t readline(int sockfd, void *buf, size_t maxline)
{
	int ret;//设置窥探返回值
	int nread;//设置已窥探字符数
	char *bufp = (char*)buf;//缓存buf
	int nleft = maxline;//设置maxline为包最大长度,nleft为剩余需读取字符数
	while(1)
	{
		ret=recv_peek(sockfd, bufp, nleft);
		if(ret<0)
		{
			return ret;
		}
		else if(ret=0)
		{
			return ret;//对方终止了传送
		}

		nread=ret;
		int i;//检测有没有‘\n’字符,有则读取
		for(i=0; i<nread,i++)
		{
			if(bufp[i]=='\n')
			{
				ret= readn(sockfd,bufp, i+1)
				if(ret != i+1)//已经窥探到有i+1字符,如果没有则错误
					exit(EXIT_FAILURE);
				return ret;
			}
		}
		//如果没有读到‘\n’,则将消息读入,直到最大包
		nleft -= nread;
		ret= readn(sockfd, bufp, nread);
		if(ret != nread)//已经窥探到有nread个字符,如果r
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值