信号駆動式IOに基づくリスニングソケット(O_ASYNC,O_NONBLOCK)
3133 ワード
背景
Source: http://blog.csdn.net/ordeder/article/details/22733077
(Unixネットワークプログラミングボリューム1の説明は以下の通り)ソケット信号駆動式io(SIGIO)を設定するには3つのステップが必要である.
1.SIGIO信号の処理関数を確立する
2.ソケットの所有者、すなわちfcntl:F_を設定するSETOWN
3.ソケットをオンにする信号駆動はIO、すなわちfcntl:O_ASYNC
ソケットにSIGIO信号を発生させる場合:
1リスニングソケットに接続要求が完了しました
-----------------------
2切断要求が開始されました
3切断要求が完了しました
4接続の半分がオフになっています
----------------------
5データ到着ソケット
6ソケットからのデータ送信
7非同期エラー発生
結び目
1から得られ、傍受ソケットは非同期信号IOに適している.
2-7非同期IOはTCP接続ソケットに適していない.
5-7入手可能、UDPは非同期信号IOに適合する
傍受ソケットの非同期信号IO
server.c
サービス側は次のように表示されます.
get sigio...
recv #client pid=2236 say hello...#
get sigio...
recv #client pid=2237 say hello...#
get sigio...
recv #client pid=2238 say hello...#
get sigio...
recv #client pid=2239 say hello...#
get sigio...
recv #client pid=2240 say hello...#
get sigio...
recv #client pid=2241 say hello...#
get sigio...
recv #client pid=2242 say hello...#
Source: http://blog.csdn.net/ordeder/article/details/22733077
(Unixネットワークプログラミングボリューム1の説明は以下の通り)ソケット信号駆動式io(SIGIO)を設定するには3つのステップが必要である.
1.SIGIO信号の処理関数を確立する
2.ソケットの所有者、すなわちfcntl:F_を設定するSETOWN
3.ソケットをオンにする信号駆動はIO、すなわちfcntl:O_ASYNC
ソケットにSIGIO信号を発生させる場合:
1リスニングソケットに接続要求が完了しました
-----------------------
2切断要求が開始されました
3切断要求が完了しました
4接続の半分がオフになっています
----------------------
5データ到着ソケット
6ソケットからのデータ送信
7非同期エラー発生
結び目
1から得られ、傍受ソケットは非同期信号IOに適している.
2-7非同期IOはTCP接続ソケットに適していない.
5-7入手可能、UDPは非同期信号IOに適合する
傍受ソケットの非同期信号IO
server.c
#include<fcntl.h>
#include<signal.h>
...
int listenfd,connfd;
void sig_iohander(int signo)
{
int rn;
char buff[128];
puts("get sigio...");
connfd = accept(listenfd,NULL,0);
if(connfd == -1){perror("accept");return;}
rn = recv(connfd,buff,127,0);
if(rn == -1) {perror("recv");return;}
buff[rn]='\0';
printf("recv #%s#
",buff);
close(connfd);
}
int main(int argc,char*argv[])
{
struct sockaddr_in cliaddr,servaddr;
int queuelen=5,i,flag;
pid_t cpid[WORKERSIZE];
listenfd = socket(AF_INET,SOCK_STREAM,0);
signal(SIGIO,sig_iohander);
flag = fcntl(listenfd,F_GETFL,0);
flag |= O_NONBLOCK | O_ASYNC;
fcntl(listenfd,F_SETFL,flag);// ( listenfd accept , , , ), IO(O_ASYNC)
fcntl(listenfd,F_SETOWN,getpid()); // listenfd
ID
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(2989);
bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
listen(listenfd,queuelen);
while(scanf("%d",&i))// io, SIGIO
~
puts("jump out of scanf block...");
return 0;
}
client.c ...
sockfd = socket(AF_INET,SOCK_STREAM,0);
rc = connect(sockfd,(struct sockaddr*)&servaddr,sizeof
(servaddr));
if(rc == -1)
{
perror("connect error");
exit(0);
}
printf("pid#%d connected...
",getpid());
char content[128];
sprintf(content,"client pid=%d say hello...",getpid());
send(sockfd,content,strlen(content),0);
shutdown(sockfd,SHUT_WR);
int rn;
while((rn == recv(sockfd,content,127,0)))//rn == 0 :
(FIN), EOF
{
content[rn] = '\0';
puts(content);
}
printf("pid#%d done...
",getpid());
...
テスト結果:サービス側は次のように表示されます.
get sigio...
recv #client pid=2236 say hello...#
get sigio...
recv #client pid=2237 say hello...#
get sigio...
recv #client pid=2238 say hello...#
get sigio...
recv #client pid=2239 say hello...#
get sigio...
recv #client pid=2240 say hello...#
get sigio...
recv #client pid=2241 say hello...#
get sigio...
recv #client pid=2242 say hello...#