Linux下的多路复用和unix套接字的综合使用

来源:互联网 发布:矩阵秩的性质 编辑:程序博客网 时间:2024/05/29 04:49
多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备好读写时,即返回可操作的描述符的数目,以下场合经常使用:
(1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。
(2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。
(3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。
(4)如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。
(5)如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。
与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。

域套接字的使用可以在不同的进程中进行通信,管道由于只能实现具有亲缘关系进程间的通讯,使用收到了很大的限制,命名管道虽然解决了这一问题,但是无论管道还是命名管道都只能实现单向通信(在只创建一个管道的情况下)

现在将两种结合在一起使用,以下为源程序,仅供参考:

服务器端程序:server.c

/*********************************************************************** 版权所有 (C)2016, GaoSheng。** 文件名称:server.c* 文件标识:无* 内容摘要:多路复用与unix域套接字的学习* 其它说明:服务器端* 当前版本:V1.0* 作    者:GaoSheng* 完成日期:20160406***********************************************************************/#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/socket.h>#include <sys/select.h>#include <sys/un.h>#include <pthread.h>#define UNIX_DOMAIN_SERVER "./SERVER"#define BUF_SIZE 1024struct sockaddr_un lo_connect_client_addr;int gUnixDomainFd_Server = -1;//服务器端的套接字int main(int argc, char *argv[]){fd_set rfds;int max_fd = 0;int ret_val = 0,readBytes = 0;char rcv_buf[BUF_SIZE] = "";int name_len = 0;//服务器端的套接字的创建与绑定unlink(UNIX_DOMAIN_SERVER);bzero(&lo_connect_client_addr,sizeof(lo_connect_client_addr));lo_connect_client_addr.sun_family = AF_UNIX;strcpy(lo_connect_client_addr.sun_path,UNIX_DOMAIN_SERVER);name_len = strlen(lo_connect_client_addr.sun_path) + sizeof(lo_connect_client_addr.sun_family);gUnixDomainFd_Server = socket(AF_UNIX,SOCK_DGRAM,0);//此处采用数据包,无连接的socket,//如果使用字节流的话就需要想TCP通讯那样进行监听if (gUnixDomainFd_Server < 0){perror("cannot created communication send socket");return -1;}if (bind(gUnixDomainFd_Server,(struct sockaddr *)&lo_connect_client_addr,name_len) < 0){perror("bind gUnixDomainFd_Server error");close(gUnixDomainFd_Server);return -1;}//读集合的初始化FD_ZERO(&rfds);if (gUnixDomainFd_Server != 1)FD_SET(gUnixDomainFd_Server,&rfds);if (gUnixDomainFd_Server > max_fd)max_fd = gUnixDomainFd_Server;//循环查询可读的文件描述符for(;;){ret_val = select(max_fd+1,&rfds,NULL,NULL,NULL);if (ret_val > 0){if (FD_ISSET(gUnixDomainFd_Server,&rfds)){memset(rcv_buf,0,BUF_SIZE);readBytes = recv(gUnixDomainFd_Server,rcv_buf,BUF_SIZE,0);if (readBytes > 0){printf("Server recevice :\n%s\n",rcv_buf);}}}}return 0;}
客户端程序:client.c

/*********************************************************************** 版权所有 (C)2016, GaoSheng。** 文件名称:server.c* 文件标识:无* 内容摘要:多路复用与unix域套接字的学习* 其它说明:客户端* 当前版本:V1.0* 作    者:GaoSheng* 完成日期:20160406***********************************************************************/#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/socket.h>#include <sys/select.h>#include <sys/un.h>#include <pthread.h>#define UNIX_DOMAIN_SERVER "./SERVER" //域套接字文件#define BUF_SIZE 1024struct sockaddr_un lo_connect_server_addr;int gUnixDomainFd_Client = -1;//客户端的套接字int main(int argc, char *argv[]){fd_set sfds;int max_fd = 0;int ret_val = 0,writeBytes = 0;struct timeval tv;char send_buf[BUF_SIZE] = "1234567";pthread_t write_pid;//初始化域套接字unlink(UNIX_DOMAIN_SERVER);bzero(&lo_connect_server_addr,sizeof(lo_connect_server_addr));lo_connect_server_addr.sun_family = AF_UNIX;strcpy(lo_connect_server_addr.sun_path,UNIX_DOMAIN_SERVER);gUnixDomainFd_Client = socket(AF_UNIX,SOCK_DGRAM,0);if (gUnixDomainFd_Client < 0){perror("cannot created communication send socket");return -1;}tv.tv_sec = 0;tv.tv_usec = 1000;//写描述符集合的初始化FD_ZERO(&sfds);if (gUnixDomainFd_Client != 1)FD_SET(gUnixDomainFd_Client,&sfds);if (gUnixDomainFd_Client > max_fd)max_fd = gUnixDomainFd_Client;//循环查询可以写的文件描述符for(;;){ret_val = select(max_fd+1,NULL,&sfds,NULL,&tv);if (ret_val > 0){if (FD_ISSET(gUnixDomainFd_Client,&sfds)){socklen_t socklen = sizeof(lo_connect_server_addr.sun_family) + strlen(lo_connect_server_addr.sun_path);writeBytes = sendto(gUnixDomainFd_Client, send_buf, strlen(send_buf), MSG_NOSIGNAL|MSG_DONTWAIT, (struct sockaddr *)&lo_connect_server_addr, socklen);if (writeBytes > 0){printf("Client send  :\n%s\n",send_buf);}}}sleep(1);}return 0;}
以上程序运行结果如下:

客户端结果:


服务器端结果:


以上仅个人理解,如有不足欢迎补充


0 0
原创粉丝点击