linux信号驱动I/O模型服务器

/*
udp服务器
 
说明:本程序为数据报服务器,用于在SIGIO信号处理程序中接受来自数据报客户端发来的数据报。收到的数据报存放在一个队列中,随后程序住循环将从队列中读取数据并进行处理
 
注意:本程序从命令行参数中获得服务器IP地址和端口,当命令行没有提供参数时,程序将使用默认值,即本机的任意IP
 
用法:./udpserver ip portnumber
*/
 
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<errno.h>
#include<string.h>
#include<time.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netdb.h>
#include<arpa/inet.f>
#include<fcntl,h>
 
#define QUESIZE 16 //队列大小
#define BUFSIZE 512
 
struct request //客户端请求
{
<span style="white-space:pre">	</span>char *reqstr;
<span style="white-space:pre">	</span>size_t reqlen;
 <span style="white-space:pre">	</span>struct sockaddr_in *peer;
<span style="white-space:pre">	</span>socklen_t sklen;
};
 
static struct request req_queue[QUESIZE];
 
static void bail(const char *on_what) //错误报告函数
{
 <span style="white-space:pre">	</span>fputs(strerror(errno),stderr);
 <span style="white-space:pre">	</span>fputs(": ",stderr);
 <span style="white-space:pre">	</span>fputs(on_what,stderr);
 <span style="white-space:pre">	</span>fputc(*\n*,stderr);
}
 
void do_sigio(int signum)
{
<span style="white-space:pre">	</span>int z;
<span style="white-space:pre">	</span>struct request *p_req;
<span style="white-space:pre">	</span>char buf[BUFSIZE];
 
for(;;)
{
<span style="white-space:pre">	</span>p_req=&req_queue[inx_in]; //保存下一个客户端请求数据包的位置索引
 
if(nqueue>=QUESIZE)
{
<span style="white-space:pre">	</span>write(stdout_FILENO,"request queue is full!\n",23);
<span style="white-space:pre">	</span>return;
}
 
z=recvfrom(s, //服务器套接字地址
q_req->reqstr, //接受缓存位置指针
BUFSIZE,
0,
(struct sockaddr*)p_req->peer, //客户端地址
&socklen);
 
if(z<0)
{
if((errno==EWOULDBLOCK)
break;
else
{
write(STDOUT_FILENO,"recvfrom error!\n",16);
exit(1);
}
}
q_req->reqstr[z]=0;
p_req->reqlen=z;
nqueue++;
 
if(++idx_in>=QUESIZE)
idx_in=0;
}
}
 
void init_queue()
{
for(int i=0;i<QUESIZE;i++)
{
if((req_queue[i].reqstr=malloc(BUFSIZE))==NULL||
(req_queue[i].peer=malloc(socklen))==NULL)
bail(init_queue");
req_queue[i].sklen=socklen;
}
idx_in=idx_out=nqueue=0;
}
 
static void install_sigio()
{
struct sigaction aigio_action;
 
memset(&sigio_action,0,sizeof(sigio_action));
sigio_action.sa_flags=0;
 
sigio_action.sa_handler=do_sigio;
 
if(sigaction(SIGIO,&sigio_action,NULL)==-1)
perror("Failed to set SIGIO");
}
 
void set_sockopt(int s,int flags)
{
fcntl(s,F_SETOWN,getpid());
if((flags=fcntl(s,F_GETFL,0))<0)
bail("F_GETFL error");
flags|=O_ASYNC|O_NONBLOCK;
if(fcntl(s,FSETFL,flags)<0)
bail("F_SETFL error");
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值