UDP信号驱动IO

SIGIO信号

信号驱动式I/O不适用于TCP套接字, 因为产生的信号过于频繁且不能准确判断信号产生的原因.
设置信号驱动需把sockfd的非阻塞与信号驱动属性都打开

server

sockfd单独提出来作为全局变量, 便于sig_io处理函数访问
num变量用于设置当前可读数据报数量
struct data结构作为信号处理函数中保存客户端信息的记录地址

#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define MAXLINE 1024
#define SERV_PORT 5555
void err_quit(const char *s){
    perror(s);
    exit(1);
}

int sockfd;

struct data{
    struct sockaddr addr;
    char data[1024];
}DATA;
static int num=0;

void sig_io(int signo){
    ssize_t nread;

    char *buff=DATA.data;
    int size=sizeof(DATA.data);
    socklen_t slen=sizeof(DATA.addr);
    nread=recvfrom(sockfd,buff,size,0,&DATA.addr,&slen);

    if(nread < 0){
        if(errno == EWOULDBLOCK)
            return;
        else
            err_quit("recvfrom");
    }
    buff[nread]=0;
    num++;
}

int main(int argc,char *argv[]){
    struct sockaddr_in servaddr;
    sockfd=socket(AF_INET,SOCK_DGRAM,0);
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
    servaddr.sin_port=htons(SERV_PORT);
    if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)
        err_quit("bind");

    int on = 1;
    signal(SIGIO,sig_io);
    fcntl(sockfd,F_SETOWN,getpid());
    ioctl(sockfd,FIOASYNC,&on);
    ioctl(sockfd,FIONBIO,&on);

    sigset_t zeromask,newmask,oldmask;
    sigemptyset(&zeromask);
    sigemptyset(&newmask);
    sigemptyset(&oldmask);
    sigaddset(&newmask,SIGIO);

    sigprocmask(SIG_BLOCK,&newmask,&oldmask);
    for(;;){
        while(num == 0)
            sigsuspend(&zeromask);

        sigprocmask(SIG_SETMASK,&oldmask,NULL);
        sendto(sockfd,DATA.data,strlen(DATA.data),0,&DATA.addr,sizeof(DATA.addr));
        sigprocmask(SIG_BLOCK,&newmask,&oldmask);
        if(num > 0)
            num--;
    }
    return 0;
}

客户端

客户端只要实现发送一次然后接受一次即可, 略

posted @ 2017-03-22 10:00  cfans1993  阅读(456)  评论(0编辑  收藏  举报