異步信號驅動IO實現回射服務器

#include "unp.h"
#include <signal.h>
/*server */
#define QSIZE 10

struct  DG{
	void *data;
	size_t datalen;
	struct sockaddr_in addr;
	socklen_t addrlen;
};

struct DG client[QSIZE];		/*循環隊列*/
int nqueue, nin, nout, sockfd;
void mydg_echo(int fd, SA * addr, socklen_t len);
void recvdata(int signo);

int main(int argc, char **argv){
	struct sockaddr_in serv, cli;
	if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
		err_sys("socket");
	bzero(&serv, sizeof(serv));
	serv.sin_family = AF_INET;
	serv.sin_port = htons(SERV_PORT);
	serv.sin_addr.s_addr = htonl(INADDR_ANY);
	bind(sockfd, (SA *)&serv, sizeof(serv));
	mydg_echo(sockfd, (SA *)&cli, sizeof(cli));
	close(sockfd);
	exit(0);
}

void mydg_echo(int fd, SA *  addr, socklen_t len){
	const int on =1;
	sigset_t zeroset, oldset, newset;
	int i, flags;
	nqueue = nin = nout = 0;
	for(i =0; i < QSIZE; i++){
		client[i].data =(char *)malloc(MAXLINE);
		client[i].addrlen = sizeof(struct sockaddr_in);
	}
	printf("t1\n");
	signal(SIGIO, recvdata);
	fcntl(fd, F_SETOWN, getpid());
	/*
		ioctl(fd, FIOASYNC, &on);
		ioctl(fd, FIONBIO, &on);
	*/
	if((flags = fcntl(fd, F_GETFL,0)) < 0)
		err_sys("fcntl1");
	flags |= O_NONBLOCK;
	flags |= O_ASYNC;
	if(fcntl(fd, F_SETFL, flags) < 0)
		err_sys("fcntl2");
	sigemptyset(&zeroset);
	sigemptyset(&oldset);
	sigemptyset(&newset);
	sigaddset(&newset, SIGIO);
	sigprocmask(SIG_BLOCK, &newset,&oldset);
	for( ; ; ){
		while(nqueue == 0){
			sigsuspend(&zeroset);
		}
		/*the SIGIO happen*/
		sigprocmask(SIG_UNBLOCK, &newset, NULL);
		sendto(fd, client[nout].data, client[nout].datalen, 0,
			(SA *)&client[nout].addr, client[nout].addrlen);
		nout++;
		nqueue --;
		if(nout >= QSIZE)
			nout = 0;
		sigprocmask(SIG_BLOCK, &newset, NULL);
	}
	sigprocmask(SIG_SETMASK, &oldset, NULL);
	return;
}

void recvdata(int signo){/*auto block SIGIO*/
	/*		printf("recvfrom \n");*/
	int n, len;
	struct sockaddr_in tmpaddr;
	char buf[MAXLINE];
	while((n = recvfrom(sockfd,client[nin].data ,  MAXLINE, 0, (SA *)&client[nin].addr, &client[nin].addrlen)) > 0){

		client[nin].datalen = n;
		//client[nin].addr = tmpaddr;
		//client[nin].data = buf;
		//client[nin].addrlen = len;
		nin++;
		nqueue ++;
		if(nin >= QSIZE)
			nin = 0;
	}
	return;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章