转自:http://blog.csdn.net/ast_224/article/details/3962221

使用socket实现进程间通信:(UNIX domain中面向连接通信)

使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。
    man unix内容如下:

NAME( 名称)
    unix, PF_UNIX, AF_UNIX, PF_LOCAL, AF_LOCAL ? 用于本地内部进程通讯的套接字。

SYNOPSIS( 总览 )
    #include <sys/socket.h>
    #include <sys/un.h>

unix_socket = socket(PF_UNIX, type, 0);
    error = socketpair(PF_UNIX, type, 0, int *sv);
DESCRIPTION( 描述 )
   
PF_UNIX (也称作 PF_LOCAL ) 套接字族用来在同一机器上的提供有效的进程间通讯.Unix 套接字可以是匿名的(由
socketpair(2)创建), 也可以与套接字类型文件相关联. Linux 还支持一种抽象名字空间, 它是独立于文件系统的.
    有效的类型有: SOCK_STREAM 用于面向流的套接字, SOCK_DGRAM 用于面向数据报的套接字,其可以保存消息界限. Unix 套接字总是可靠的,而且不会重组数据报.
    Unix 套接字支持把文件描述符或者进程的信用证明作为数据报的辅助数据传递给 其它进程.
ADDRESS FORMAT( 地址格式 )
   
unix 地址定义为文件系统中的一个文件名或者抽象名字空间中的一个单独的字符串. 由 socketpair(2)
创建的套接字是匿名的.对于非匿名的套接字,目标地址 可使用 connect(2) 设置. 本地地址可使用 bind(2) 设置.
当套接字连接上而且它没有一个本地地址时, 会自动在抽象名字空间中生成一个唯一的地址.
    #define UNIX_PATH_MAX   108

struct sockaddr_un {
    sa_family_t     sun_family;     /* AF_UNIX */
    char    sun_path[UNIX_PATH_MAX];        /* 路径名 */
    };
   
sun_family 总是包含 AF_UNIX. sun_path 包含空零结尾的套接字在文件系统中的路径名. 如果 sun_path
以空零字节开头,它指向由 Unix 协议模块维护的抽象名字空间. 该套接字在此名字空间中的地址由 sun_path 中的剩余字节给定.
注意抽象名字空间的名字都不是空零终止的.
SOCKET OPTIONS( 套接字选项 )
    由 于 历 史 原 因,
这些套接字选项通过 SOL_SOCKET 类型确定, 即使它们是 PF_UNIX 指定的. 它们可以由 setsockopt(2) 设置.
通过指定 SOL_SOCKET 作 为套接字族用 getsockopt(2) 来读取.
    SO_PASSCRED 允许接收进程辅助信息发送的信用证明. 当设置了该选项且套接字 尚未连接时, 则会自动生成一个抽象名字空间的唯一名字. 值为一个整数布尔标 识.
ANCILLARY MESSAGES( 辅助信息 )
   
由 于 历 史 原 因, 这些辅助信息类型通过 SOL_SOCKET 类型确定, 即使它们是 PF_UNIX 指定的. 要发送它们,
可设置结构 cmsghdr 的 cmsg_level 字 段 为 SOL_SOCKET, 并 设 置 cmsg_type 字段为其类型.
要获得更多信息, 请参看 cmsg(3).
    SCM_RIGHTS
    为其他进程发送或接收一套打开文件描述符. 其数据部分包含一个文件 描述符的整型数组. 已传文件描述符的效果就如它们已由 dup(2) 创建 过一样.
    SCM_CREDENTIALS
    发送或者接收 unix 信用证明. 可用作认证.信用证明传送 以 struct ucred 辅助信息的形式传送.
    struct ucred {
    pid_t   pid;     /* 发送进程的进程标识 */
    uid_t   uid;     /* 发送进程的用户标识 */
    gid_t   gid;     /* 发送进程的组标识 */
    };
   
发 送者确定的信用证明由内核检查. 一个带有有效用户标识 0 的进程允许指定 不与其自身值相匹配的值.发送者必须确定其自身的进程 标 识(
除非它带 有 CAP_SYS_ADMIN), 其 用 户 标识,有效用户标识或者设置用户标识(除非它带有CAP_SETUID),
以及其组标识,有效组标识或者 设 置 组 标 识( 除非它带有CAP_SETGID). 为 了 接 收 一 条 struct ucred
消息,必须在套接字上激活 SO_PASSCRED 选项.
ERRORS( 错误 )
    ENOMEM
        内存溢出.
   
    ECONNREFUSED
        connect(2) 调用了一个未在监听的套接字对象. 这可能发生在远程套 接字不存在或者文件名不是套接字的时候.
    EINVAL
        传递了无效参数. 通常的产生原因是已传地址的 sun_type 字 段的 AF_UNIX 设置丢失, 或者套接字对应用的操作处于无效状态.
    EOPNOTSUPP
        在非面向流的套接字上调用了流操作,或者试图使用出界的数据选项.
    EPROTONOSUPPORT
        传递的协议是非 PF_UNIX 的.
    ESOCKTNOSUPPORT
        未知的套接字类型.
    EPROTOTYPE
        远程套接字与本地套接字类型不匹配 (SOCK_DGRAM 对SOCK_STREAM).
    EADDRINUSE
        选择的本地地址已经占用,或者文件系统套接字对象已经存在.
    EISCONN
        在 一个已经连接的套接字上调用 connect(2) 或者指定的目标地址在一 个已连接的套接字上.
    ENOTCONN
        套接字操作需要一个目的地址,但是套接字尚未连接.
    ECONNRESET
        远程套接字意外关闭.
    EPIPE
        远程套接字在一个流套接字上关闭了.如果激活,会同时发送一个 SIGPIPE 标识.这可以通过传递 MSG_NOSIGNAL 标识给 sendmsg(2) 或者 recvmsg(2) 来避免.
    EFAULT
        用户内存地址无效.
    EPERM
        发送者在 struct ucred 中传递无效的信用证明.
    当生成一个文件系统套接字对象时, 可能会由通用套接层或者文件系统产生其它错误. 要获得更多信息,可参见合适的手册页.

实践:

使用套接字在UNIX域内实现进程间通信的服务端程序。首先,程序通过调用socket函数,建立了监听连接的套接字,然后调用bind函数,将套接字与
地址信息关联起来。调用listen函数实现对该端口的监听,当有连接请求时,通过调用accept函数建立与客户机的连接,最后,调用read函数来读
取客户机发送过来的消息,当然也可以使用recv函数实现相同的功能。

server代码:s_unix.c

    //s_unix.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define UNIX_DOMAIN "/tmp/UNIX.domain"
int main(void)
{
socklen_t clt_addr_len;
int listen_fd;
int com_fd;
int ret;
int i;
static char recv_buf[];
int len;
struct sockaddr_un clt_addr;
struct sockaddr_un srv_addr;
listen_fd=socket(PF_UNIX,SOCK_STREAM,);
if(listen_fd<)
{
perror("cannot create communication socket");
return ;
} //set server addr_param
srv_addr.sun_family=AF_UNIX;
strncpy(srv_addr.sun_path,UNIX_DOMAIN,sizeof(srv_addr.sun_path)-);
unlink(UNIX_DOMAIN);
//bind sockfd & addr
ret=bind(listen_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
if(ret==-)
{
perror("cannot bind server socket");
close(listen_fd);
unlink(UNIX_DOMAIN);
return ;
}
//listen sockfd
ret=listen(listen_fd,);
if(ret==-)
{
perror("cannot listen the client connect request");
close(listen_fd);
unlink(UNIX_DOMAIN);
return ;
}
//have connect request use accept
len=sizeof(clt_addr);
com_fd=accept(listen_fd,(struct sockaddr*)&clt_addr,&len);
if(com_fd<)
{
perror("cannot accept client connect request");
close(listen_fd);
unlink(UNIX_DOMAIN);
return ;
}
//read and printf sent client info
printf("/n=====info=====/n");
for(i=;i<;i++)
{
memset(recv_buf,,);
int num=read(com_fd,recv_buf,sizeof(recv_buf));
printf("Message from client (%d)) :%s/n",num,recv_buf);
}
close(com_fd);
close(listen_fd);
unlink(UNIX_DOMAIN);
return ;
}

使用套接字在UNIX域内实现进程间通信的客户端程序。相比服务端的程序,客户段较为简单。程序首先通过调用socket函数创建通信所需的套接字,然后,调用connect函数来连接服务器,在成功建立连接后,通过调用write函数向服务器发送指定的消息。

client代码:u_unix.c

    //c_unix.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define UNIX_DOMAIN "/tmp/UNIX.domain"
int main(void)
{
int connect_fd;
int ret;
char snd_buf[];
int i;
static struct sockaddr_un srv_addr;
//creat unix socket
connect_fd=socket(PF_UNIX,SOCK_STREAM,);
if(connect_fd<)
{
perror("cannot create communication socket");
return ;
}
srv_addr.sun_family=AF_UNIX;
strcpy(srv_addr.sun_path,UNIX_DOMAIN);
//connect server
ret=connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
if(ret==-)
{
perror("cannot connect to the server");
close(connect_fd);
return ;
}
memset(snd_buf,,);
strcpy(snd_buf,"message from client");
//send info server
for(i=;i<;i++)
write(connect_fd,snd_buf,sizeof(snd_buf));
close(connect_fd);
return ;
}

编译运行:

[root@localhost liuxltest]# ./s_unix &
[1] 11664
[root@localhost liuxltest]# ./c_unix &

=====info=====
Message from client (1024)) :message from client
Message from client (1024)) :message from client
Message from client (1024)) :message from client
Message from client (1024)) :message from client
[2] 11665
[1]-  Done                    ./s_unix
[2]+  Done                    ./c_unix
[root@localhost liuxltest]#

当运行s_unix程序后,该程序将处于监听状态。这时,可以通过netstat命令查看程序运行情况,s_unix的套接字类型为流套接字,并处于监听状态。
[root@localhost liuxltest]#
[root@localhost liuxltest]# ./s_unix &
[1] 12056
[root@localhost liuxltest]# netstat -an |grep /tmp
unix  2      [ ACC ]     STREAM     LISTENING     64014  /tmp/ssh-CekOJ11069/agent.11069
unix  2      [ ACC ]     STREAM     LISTENING     6216   /tmp/.font-unix/fs7100
unix  2      [ ACC ]     STREAM     LISTENING     62042  /tmp/ssh-XOCgkr9439/agent.9439
unix  2      [ ACC ]     STREAM     LISTENING     62316  /tmp/ssh-mojoaQ9648/agent.9648
unix  2      [ ACC ]     STREAM     LISTENING     65267  /tmp/UNIX.domain
unix  2      [ ACC ]     STREAM     LISTENING     65210  /tmp/ssh-NlKtA12012/agent.12012
[root@localhost liuxltest]#

socket实现进程间通信(转载)的更多相关文章

  1. 理解Socket编程【转载】

    “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...

  2. 细说linux IPC(一):基于socket的进程间通信(上)

        [版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途]     在一个较大的project其中 ...

  3. socket.io(转载)

    socket.io 中文手册,socket.io 中文文档转载于:http://www.cnblogs.com/xiezhengcai/p/3956401.html 服务端 io.on(‘connec ...

  4. Socket编程——(转载)

    我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠so ...

  5. Socket桥(转载)

    最好方案:使用haproxy 或者nginx转发.自己写程序性能和监控难保证,推荐使用开源软件替代. 源地址为:http://baishaobin2003.blog.163.com/blog/stat ...

  6. linux下socket编程-进程间通信

    一.什么是Socket Socket接口是TCP/IP网络通信的API,Socket接口定义了许多函数或例程,可以用它们来开发TCP/IP网络上的应用程序. Socket类型有两种:流式Socket ...

  7. win32下Socket编程(转载)

    在网上找了很多的资料,现将这些资料整合起来,详细介绍一下VC下的socket编程,并提供一个服务器客户端具体的实例.希望对您有所帮助 一.原理部分 (个人觉得这篇写的可以,所以转与此,原文地址:htt ...

  8. java Socket(详解)转载

    在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器 ...

  9. Java Socket 通信实例 - 转载

    基于Tcp协议的简单Socket通信实例(JAVA)   好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些 ...

随机推荐

  1. HDU 6437 最(大) 小费用最大流

    Problem L.Videos Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Other ...

  2. POJ 2484 A Funny Game【博弈】

    相比数据结构的题..感觉这种想啊想的题可爱多了~~~代码量还少.... 题目链接: http://poj.org/problem?id=2484 题意: 一圈n个硬币,两人轮流从中取一或两个硬币,(只 ...

  3. [Bzoj1034][ZJOJ2008]泡泡堂BNB(贪心)

    1034: [ZJOI2008]泡泡堂BNB Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3482  Solved: 1776[Submit][St ...

  4. AtCoder Regular Contest 091&092

    091E(构造) 题意: 给出n,a,b.你需要构造出一个长度为n的n的排列,其中最长上升子序列的长度为a,最长下降子序列的长度为b. n,a,,b<=3e5 分析: 我们可以构造出这样的数列, ...

  5. Wannafly模拟赛2 C alliances(dfs序+二分)

    题目 https://www.nowcoder.com/acm/contest/4/C 题意 由n个点组成一个树,有m个帮派,每个帮派由一些个点组成,这些点以及它们两两路径上的所有点都属于该帮派的管辖 ...

  6. 检测socket链接是否断开

    [解决方案]   1. 发送重试,由业务完成.     因为club_l5的send接口不会保留用户发送的内容,在recv失败的情况下,用户发送的数据已经丢失,所以只能由业务进行重试.     结论: ...

  7. Go和HTTPS(TLS)

    原文链接: http://studygolang.com/wr?u=http%3a%2f%2ftonybai.com%2f2015%2f04%2f30%2fgo-and-https%2f 近期在构思一 ...

  8. DNS的工作原理及解析

    DNS协议是互联网核心协议之一.不管是上网浏览,还是编程开发,都需要了解一点它的知识. 一.什么是DNS? DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次 ...

  9. java File_encoding属性

    今天给客户发版本号,突然发现报表导出内容为空,大小0字节.感到很奇怪,由于开发的时候都好好的,打包出来怎么会出现异常. 细看才后发现是 file_encoding这个java系统属性编码方式设置导致的 ...

  10. 避免使用vector&lt;bool&gt;

     作为一个STL容器,vector<bool>仅仅有两点不正确. 首先.它不是一个STL容器. 其次,它并不存储bool.除此之外.一切正常. 一个对象要成为容器,就必须满足C++标准 ...