Linux中国论坛's Archiver

lydr 发表于 2006-12-15 16:41

使用aio写socket通信程序

发送端代码
[code]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/in.h>                 /*socket address struct*/
#include <arpa/inet.h>                        /*host to network convertion*/
#include <sys/socket.h>
#include <signal.h>
#define MAX_TRANSPORT_LENTH 512

int main()
{
        struct sockaddr_in addr;
        memset(&addr,0,sizeof(addr));
        addr.sin_family =  AF_INET;
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        addr.sin_port = htons(50001);
       
        int sock;
        sock = socket(AF_INET,SOCK_DGRAM,0);
        if(sock == -1)
        {
                perror("Create socket failed");
                exit(-1);
        }
       
        int ret;
        ret = connect(sock,(struct sockaddr *)&addr,sizeof(addr));
        if(ret == -1)
        {
                perror("Connect socket failed");
                exit(-1);               
        }               
        while(1)
        {
                printf("Will send messge to server\n");
                write(sock,"Some unknown infomation\n",MAX_TRANSPORT_LENTH);
                sleep(1);
        }
       
}
[/code]
发送端同上篇帖子相比,没啥区别。
主要不同的在于接收端,因为是采用了aio,所以很有些不同
接收端代码
[code]
#include <aio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/in.h>                 /*socket address struct*/
#include <arpa/inet.h>                        /*host to network convertion*/
#include <sys/socket.h>
#include <sys/types.h>
#include <signal.h>
//#include <sys/ioctl.h>
#define MAX_TRANSPORT_LENTH 512
#define MAX_LIST                5

void sig_handler(int signo, siginfo_t *info, void *context )
{
        int ret;
        struct aiocb *req;
        /* Ensure it's our signal */
        if (info->si_signo == SIGIO) {

                req = (struct aiocb *)info->si_value.sival_ptr;
                if (aio_error( req ) == 0) {
                        ret = aio_return( req );
                        (char*)(req->aio_buf+ret) == '\0';
                        puts(req->aio_buf);
                }

        }

        return;       
}

int main()
{
        int skt_fd,ret;
        struct aiocb my_aiocb;
        struct sigaction sig_act;
       
        struct sockaddr_in addr;
        memset(&addr,0,sizeof(addr));
        addr.sin_family =  AF_INET;
        addr.sin_addr.s_addr = INADDR_ANY;
        addr.sin_port = htons(50001);
       
       
        skt_fd = socket(AF_INET, SOCK_DGRAM, 0);
        if(skt_fd == -1)
        {
                perror("Create socket failed");
                exit(-1);
        }
        ret = bind(skt_fd,(struct sockaddr *)&addr,sizeof(addr));
        if(-1 == ret)
        {
                perror("Bind socket failed");
                exit(-1);
        }

        memset(&my_aiocb,0,sizeof(my_aiocb));
        my_aiocb.aio_buf = malloc(MAX_TRANSPORT_LENTH+1);       
        if (!my_aiocb.aio_buf)
                perror("malloc");
       
        my_aiocb.aio_fildes = skt_fd;
        my_aiocb.aio_nbytes = MAX_TRANSPORT_LENTH;
        my_aiocb.aio_offset = 0;
       
        my_aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
        my_aiocb.aio_sigevent.sigev_signo = SIGIO;
        my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb;

       
        sigemptyset(&sig_act.sa_mask);
        sig_act.sa_flags = SA_SIGINFO;
        sig_act.sa_sigaction = sig_handler;       
       
        const struct aiocb *cblist[MAX_LIST] ={&my_aiocb,NULL,NULL,NULL,NULL};
        sigaction( SIGIO, &sig_act, NULL );
       
        ret = aio_read( &my_aiocb );       
        //程序挂起直到等到某个信号
        while ( aio_suspend( cblist, MAX_LIST, NULL ) == 0)
        {
            ret = aio_read( &my_aiocb );
        };
        puts("Interrupted finish.");
        close(skt_fd);       
}
[/code]
在这里,如果用my_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD;
则可以指定一个回调函数来完成读取数据的操作,这种方法还是希望对此文感兴趣的伙伴加以完善吧。

lauxp 发表于 2007-3-19 10:26

SIGIO不是AIO吧,只能算是非诸塞同步IO吧?

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.