|
看过realtang写的aio程序,确实很棒,代码很精简。
这是我的测试用例,分享一下
- #include <aio.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <string.h>
- #include <errno.h>
- #define SA struct sockaddr
- #define LISTENPORT 8888
- #define BACKLOG 1024
- /* 编译的时候加 -lrt 参数 real-time 库 */
- static char buf[BUFSIZ];
- static struct aiocb aio;
- static connfd; /* connection socket descriptor */
- static global_quit_flag;
- void signal_handler(void);
- void sig_chld(int signo);
- void sig_io(int signo);
- int create_listenfd(void);
- void do_loop(int listenfd);
- void do_request(void);
- void init_aio(void);
- void err_sys(const char *errmsg);
- int main(void)
- {
- int listenfd;
- signal_handler();
- listenfd = create_listenfd();
- do_loop(listenfd);
- exit(0);
- }
- void signal_handler(void)
- {
- struct sigaction sigio_act, sigchld_act;
- sigio_act.sa_handler = sig_io;
- sigio_act.sa_flags = 0;
- if (sigemptyset(&sigio_act.sa_mask) == -1)
- err_sys("sigemptyset");
- else if (sigaction(SIGIO, &sigio_act, NULL) == -1)
- err_sys("sigaction");
- sigchld_act.sa_handler = sig_chld;
- sigchld_act.sa_flags = 0;
- if (sigemptyset(&sigchld_act.sa_mask) == -1)
- err_sys("sigemptyset");
- else if (sigaction(SIGCHLD, &sigchld_act, NULL) == -1)
- err_sys("sigaction");
- }
- int create_listenfd(void)
- {
- int listenfd;
- struct sockaddr_in servaddr;
- if ((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
- err_sys("socket");
- bzero(&servaddr, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(LISTENPORT);
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard address */
- if (bind(listenfd, (SA *)&servaddr, sizeof(servaddr)) == -1)
- err_sys("bind");
- else if (listen(listenfd, BACKLOG) == -1)
- err_sys("listen");
- return listenfd;
- }
- void do_loop(int listenfd)
- {
- pid_t pid;
- for (;;) { /* forever process client request */
- if ((connfd = accept(listenfd, NULL, NULL)) == -1) {
- if (errno == EINTR)
- continue;
- else
- err_sys("accept");
- }
- if ((pid = fork()) == -1)
- err_sys("fork");
- else if (pid == 0) { /* child process */
- if (close(listenfd) == -1)
- err_sys("close");
- do_request();
- for (;;) {
- if (global_quit_flag == 1)
- break; /* jump out loop */
- pause();
- }
- exit(0);
- }
- if (close(connfd) == -1)
- err_sys("close");
- }
- }
- void do_request(void)
- {
- init_aio();
- if (aio_read(&aio) == -1)
- err_sys("aio_read");
- }
- void init_aio(void)
- {
- aio.aio_fildes = connfd;
- aio.aio_offset = 0;
- aio.aio_buf = buf;
- aio.aio_nbytes = BUFSIZ;
- aio.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- aio.aio_sigevent.sigev_signo = SIGIO;
- aio.aio_sigevent.sigev_value.sival_ptr = &aio;
- }
- void sig_chld(int signo)
- {
- while (waitpid(-1, NULL, WNOHANG) > 0)
- /* wait child process */;
- }
- void sig_io(int signo)
- {
- int n;
- if (aio_error(&aio) == 0) { /* I/O execute complete */
- n = aio_return(&aio);
- if (n == 0) {
- global_quit_flag = 1; /* client close connection */
- return ;
- }
- if (send(connfd, (char *)aio.aio_buf, n, 0) != n)
- err_sys("send");
- do_request();
- }
- }
- void err_sys(const char *errmsg)
- {
- perror(errmsg);
- exit(1);
- }
复制代码 |
|