免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2912 | 回复: 1
打印 上一主题 下一主题

在 Linux 上实现基于 Socket 的多进程实时通信 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-20 00:05 |只看该作者 |倒序浏览

在 Linux 上实现基于 Socket 的多进程实时通信
作者: 恒善喜   发布日期: 2006-7-03    查看数:
267267    出自: http://www.linuxdiyf.com

级别: 初级
周欣, 软件工程师
2005 年 3 月 01 日
套接口(Socket)为目前 Linux 上最为广泛使用的一种的进程间通信机制。但是它不能直接用来多进程之间的相互实时通信。本文提出一个基于 Socket 的多进程之间通信的实现方法,并给出样本程序的实现和说明。
套接口(Socket)为目前Linux上最为广泛使用的一种的进程间通信机制,与其他的Linux通信机制不同之处在于除了它可用于单机内的进程间通信以外,还可用于不同机器之间的进程间通信。但是由于Socket本身不支持同时等待和超时处理,所以它不能直接用来多进程之间的相互实时通信。
本文提出一个基于Socket的多进程之间通信的实现方法。原理是建立一个进程专门用来做为通信服务器(server)来中转各个进程之间的通信。它首先启动一个用来监视连接要求的listening Socket,并把它的描述(Descriptor)号加入到一个事先定义好的fd_set的集合中,这个fd_set的集合用来存放listening Socket和后来生成的通信Socket的描述号。Server运用system call select来实时检查是否有数据到达这个集合中的任何一个socket,如果有数据到达listening Socket,则这一定是客户端发起的连接请求,于是生成一个新的通信Socket与该客户端连接,将生成的Socket描述号加入到fd_set的集合中,将客户端的ID号和与之对应的Socket的描述号记录在ID登记表中。如果有数据到达某个通信Socket,则这一定是某个客户端发起的通信请求,读出数据并取出收信客户端ID号,在ID登记表中找到与之对应的Socket描述号,将数据通过对应Socket传送到收信客户端。
其他各进程作为客户端(client)。客户端的动作是首先建立通信Socket连接服务器端,然后通过通信Socket进行送信和收信。
下面给出具体的程序实现和说明,
首先给出Server端的程序,在这里假设有两个客户端要进行实时通信,ClientA向ClientB发送字符1,ClientB向ClientA发送字符2。
QUOTE:
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
int rcd ;
struct sockaddr_un server_sockaddr ;
int backlog ;
ushort ci ;
int watch_fd_list[3] ;
fd_set catch_fd_set ;
fd_set watchset ;
int new_cli_fd ;
int maxfd;
int socklen ,server_len;
struct sockaddr_un cli_sockaddr ;
struct {
char module_id ; /* Module ID */
int cli_sock_fd ; /* Socket ID */
} cli_info_t[2] ;
for (ci=0;ci
在上面的程序中,Server生成listening Socket(server_sockfd),初始化Socket监视集合(watchset),并将listening Socket放入Socket监视集合中。
QUOTE:
while (1){
char ch;
int fd;
int nread;
catch_fd_set=watchset;
rcd = select( maxfd+1, &catch_fd_set, NULL, NULL, (struct timeval *)0 ) ;
在上面的程序中,Server运用系统调用函数 select来实时检查是否有数据到达Socket监视集合中的任何一个socket。
QUOTE:
if ( rcd
在上面的程序中,Server运用系统调用函数FD_ISSET来检查是否有客户端的连接请求到达Listening Socket, 如果返回值大于0,Server生成一个新的通信Socket (new_cli_fd)与客户端连接。将新生成的通信Socket放入Socket监视集合中(FD_SET)。将客户端的信息(ID号和Socket 描述号)保存在注册表cli_info_t中
QUOTE:
for ( ci = 1; ci
在上面的程序中,如果有数据到达某个通信Socket,Server则读出数据并取出收信客户端ID号。在ID登记表中找到收信客户端对应的Socket描述号。并将数据通过对应Socket传送到收信客户端
给出客户端 ClientA的程序
ClientB的程序只需将 char dst_module_id='B'; 改为char dst_module_id='A'; char ch='1'; 改为char char ch='2';既可。
QUOTE:
#include
#include
#include
#include
#include
#include
#include
int main(){
int client_sockfd;
int len;
struct sockaddr_un server_sockaddr,cli_sockaddr;
int result;
char dst_module_id='B';
char ch='1';
char src_module_id;
client_sockfd= socket(AF_UNIX,SOCK_STREAM,0);
cli_sockaddr.sun_family = AF_UNIX ;
strcpy( cli_sockaddr.sun_path, "A" ) ;
bind(client_sockfd,(struct sockaddr * )&cli_sockaddr, sizeof( cli_sockaddr ) ) ;
server_sockaddr.sun_family=AF_UNIX;
strcpy( server_sockaddr.sun_path, "server_socket" ) ;
len=sizeof(server_sockaddr);
result = connect(client_sockfd,( struct sockaddr * )&server_sockaddr,len);
if (result
下面是样本程序的执行结果
[root@zhou test]# ./server &
[3] 4301
[root@zhou test]# SERVER::Server is waitting on socket=3
./clientA & ./clientB &
[4] 4302
[5] 4303
ClientA::succeed in connecting with server
SERVER::open communication with Client A on socket 4
[root@zhou test]# SERVER::open communication with Client B on socket 5
ClientB::succeed in connecting with server
SERVER::char=1 to Client B on socket5
ClientB::char from Client A =1
SERVER::char=2 to Client A on socket4
ClientA::char from Client B =2
程序清单下载:server.c:
http://www-128.ibm.com/developer ... socket-ipc/server.c
clientA.c:
http://www-128.ibm.com/developer ... ocket-ipc/clientA.c
关于作者
周欣,北京邮电大学计算机系硕士毕业, 现在日本从事软件开发,通过
jones_zhou@yahoo.com.cn
可以和他联系。
SERVER.c
#include  
#include
#include
#include
#include
#include
#include
#include
int main()
{
        int                                rcd ;
        struct sockaddr_un        server_sockaddr ;
        int                                backlog ;
        ushort                                ci ;
        int                                watch_fd_list[3] ;
        fd_set                                catch_fd_set ;
        fd_set                                watchset ;
        int        new_cli_fd ;
        int         maxfd;
        int        socklen,server_len;
        struct sockaddr_un        cli_sockaddr ;
        struct {
                char                module_id ;                /* Module ID                        */
                int                cli_sock_fd ;        /* Socket ID                */
        } cli_info_t[2] ;
       
        for (ci=0;ci
CLIENT.c
#include  
#include
#include
#include
#include
#include
#include
int main(){
       
        int client_sockfd;
        int len;
        struct sockaddr_un server_sockaddr,cli_sockaddr;
        int result;
        char dst_module_id='B';
        char ch='1';
        char src_module_id;
       
       
        client_sockfd= socket(AF_UNIX,SOCK_STREAM,0);
       
//        memset( &cli_sockaddr, 0, sizeof( cli_sockaddr) ) ;
        cli_sockaddr.sun_family = AF_UNIX ;
        strcpy( cli_sockaddr.sun_path, "A" ) ;
        bind( client_sockfd, ( struct sockaddr * )&cli_sockaddr, sizeof( cli_sockaddr ) ) ;
        server_sockaddr.sun_family=AF_UNIX;
//        server_sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
//        server_sockaddr.sin_port=htons(9734);
        strcpy( server_sockaddr.sun_path, "server_socket" ) ;
        len=sizeof(server_sockaddr);
       
        result = connect(client_sockfd,( struct sockaddr * )&server_sockaddr,len);
        if (result

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/27131/showart_343197.html

论坛徽章:
0
2 [报告]
发表于 2011-06-12 09:20 |只看该作者
都是一样的文章在转啊,有没有原创的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP