04Linux网络编程基础 ---- 信号

1. 统一事件源:

04Linux网络编程基础 ---- 信号
  1 #include <sys/types.h>
  2 #include <sys/socket.h>
  3 #include <netinet/in.h>
  4 #include <arpa/inet.h>
  5 #include <assert.h>
  6 #include <stdio.h>
  7 #include <signal.h>
  8 #include <unistd.h>
  9 #include <errno.h>
 10 #include <string.h>
 11 #include <fcntl.h>
 12 #include <stdlib.h>
 13 #include <sys/epoll.h>
 14 #include <pthread.h>
 15 
 16 #define MAX_EVENT_NUMBER 1024
 17 static int pipefd[2];
 18 
 19 int setnonblocking( int fd )
 20 {
 21     int old_option = fcntl( fd, F_GETFL );
 22     int new_option = old_option | O_NONBLOCK;
 23     fcntl( fd, F_SETFL, new_option );
 24     return old_option;
 25 }
 26 
 27 void addfd( int epollfd, int fd )
 28 {
 29     epoll_event event;
 30     event.data.fd = fd;
 31     event.events = EPOLLIN | EPOLLET;
 32     epoll_ctl( epollfd, EPOLL_CTL_ADD, fd, &event );
 33     setnonblocking( fd );
 34 }
 35 
 36 void sig_handler( int sig )
 37 {
 38     int save_errno = errno;
 39     int msg = sig;
 40     send( pipefd[1], ( char* )&msg, 1, 0 );
 41     errno = save_errno;
 42 }
 43 
 44 void addsig( int sig )
 45 {
 46     struct sigaction sa;
 47     memset( &sa, \0, sizeof( sa ) );
 48     sa.sa_handler = sig_handler;
 49     sa.sa_flags |= SA_RESTART;
 50     sigfillset( &sa.sa_mask );
 51     assert( sigaction( sig, &sa, NULL ) != -1 );
 52 }
 53 
 54 int main( int argc, char* argv[] )
 55 {
 56     if( argc <= 2 )
 57     {
 58         printf( "usage: %s ip_address port_number\n", basename( argv[0] ) );
 59         return 1;
 60     }
 61     const char* ip = argv[1];
 62     int port = atoi( argv[2] );
 63 
 64     int ret = 0;
 65     struct sockaddr_in address;
 66     bzero( &address, sizeof( address ) );
 67     address.sin_family = AF_INET;
 68     inet_pton( AF_INET, ip, &address.sin_addr );
 69     address.sin_port = htons( port );
 70 
 71     int listenfd = socket( PF_INET, SOCK_STREAM, 0 );
 72     assert( listenfd >= 0 );
 73 
 74     //int nReuseAddr = 1;
 75     //setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &nReuseAddr, sizeof( nReuseAddr ) );
 76     ret = bind( listenfd, ( struct sockaddr* )&address, sizeof( address ) );
 77     if( ret == -1 )
 78     {
 79         printf( "errno is %d\n", errno );
 80         return 1;
 81     }
 82     //assert( ret != -1 );
 83 
 84     ret = listen( listenfd, 5 );
 85     assert( ret != -1 );
 86 
 87     epoll_event events[ MAX_EVENT_NUMBER ];
 88     int epollfd = epoll_create( 5 );
 89     assert( epollfd != -1 );
 90     addfd( epollfd, listenfd );
 91 
 92     ret = socketpair( PF_UNIX, SOCK_STREAM, 0, pipefd );
 93     assert( ret != -1 );
 94     setnonblocking( pipefd[1] );
 95     addfd( epollfd, pipefd[0] );
 96 
 97     // add all the interesting signals here
 98     addsig( SIGHUP );
 99     addsig( SIGCHLD );
100     addsig( SIGTERM );
101     addsig( SIGINT );
102     printf("SIGHUP:%d, SIGCHLD:%d, SIGTERM:%d, SIGINT:%d\n", SIGHUP, SIGCHLD, SIGTERM, SIGINT);
103     bool stop_server = false;
104 
105     while( !stop_server )
106     {
107         int number = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 );
108         if ( ( number < 0 ) && ( errno != EINTR ) )
109         {
110             printf( "epoll failure\n" );
111             break;
112         }
113     
114         for ( int i = 0; i < number; i++ )
115         {
116             int sockfd = events[i].data.fd;
117             if( sockfd == listenfd )
118             {
119                 struct sockaddr_in client_address;
120                 socklen_t client_addrlength = sizeof( client_address );
121                 int connfd = accept( listenfd, ( struct sockaddr* )&client_address, &client_addrlength );
122                 addfd( epollfd, connfd );
123             }
124             else if( ( sockfd == pipefd[0] ) && ( events[i].events & EPOLLIN ) )
125             {
126                 int sig;
127                 char signals[1024];
128                 ret = recv( pipefd[0], signals, sizeof( signals ), 0 );
129                 if( ret == -1 )
130                 {
131                     continue;
132                 }
133                 else if( ret == 0 )
134                 {
135                     continue;
136                 }
137                 else
138                 {
139                     for( int i = 0; i < ret; ++i )
140                     {
141                         printf( "I caugh the signal %d\n", signals[i] );
142                         switch( signals[i] )
143                         {
144                             case SIGCHLD:
145                             case SIGHUP:
146                             {
147                                 continue;
148                             }
149                             case SIGTERM: // kill pid
150                             case SIGINT: // 键盘Ctrl+C
151                             {
152                                 stop_server = true;
153                             }
154                         }
155                     }
156                 }
157             }
158             else
159             {
160             }
161         }
162     }
163 
164     printf( "close fds\n" );
165     close( listenfd );
166     close( pipefd[1] );
167     close( pipefd[0] );
168     return 0;
169 }
View Code

运行:

[zf@localhost 10]$ ./a.out 127.0.0.1 1236
SIGHUP:1, SIGCHLD:17, SIGTERM:15, SIGINT:2
^CI caugh the signal 2 (执行Ctrl + C)
close fds
[zf@localhost 10]$ ./a.out 127.0.0.1 1237
SIGHUP:1, SIGCHLD:17, SIGTERM:15, SIGINT:2
I caugh the signal 15 (被kill杀死)
close fds

2.信号函数

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
 struct sigaction {
               void     (*sa_handler)(int); // 信号处理函数
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask; // 信号掩码
               int        sa_flags; // 设置信号行为
               void     (*sa_restorer)(void);
           };
signum:信号类型
act: 新的信号处理
oact:返回之前的信号处理

04Linux网络编程基础 ---- 信号

上一篇:守护进程,锁,队列(生产者消费者模型)


下一篇:PDFSharp生成PDF (转)