问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

进程间通讯 使用socket len长度

发布网友 发布时间:2022-06-02 14:07

我来回答

1个回答

热心网友 时间:2023-10-31 22:15

使用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
为其他进程发送或接收一套打开文件描述符. 其数据部分包含一个文件 描述符的整型数组. 已传文件描述符的效果就如它们已由 p(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

[c-sharp] view plain copy
//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[1024];
int len;
struct sockaddr_un clt_addr;
struct sockaddr_un srv_addr;
listen_fd=socket(PF_UNIX,SOCK_STREAM,0);
if(listen_fd<0)
{
perror("cannot create communication socket");
return 1;
}

//set server addr_param
srv_addr.sun_family=AF_UNIX;
strncpy(srv_addr.sun_path,UNIX_DOMAIN,sizeof(srv_addr.sun_path)-1);
unlink(UNIX_DOMAIN);
//bind sockfd & addr
ret=bind(listen_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
if(ret==-1)
{
perror("cannot bind server socket");
close(listen_fd);
unlink(UNIX_DOMAIN);
return 1;
}
//listen sockfd
ret=listen(listen_fd,1);
if(ret==-1)
{
perror("cannot listen the client connect request");
close(listen_fd);
unlink(UNIX_DOMAIN);
return 1;
}
//have connect request use accept
len=sizeof(clt_addr);
com_fd=accept(listen_fd,(struct sockaddr*)&clt_addr,&len);
if(com_fd<0)
{
perror("cannot accept client connect request");
close(listen_fd);
unlink(UNIX_DOMAIN);
return 1;
}
//read and printf sent client info
printf("/n=====info=====/n");
for(i=0;i<4;i++)
{
memset(recv_buf,0,1024);
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 0;
}

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

[c-sharp] view plain copy
//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[1024];
int i;
static struct sockaddr_un srv_addr;
//creat unix socket
connect_fd=socket(PF_UNIX,SOCK_STREAM,0);
if(connect_fd<0)
{
perror("cannot create communication socket");
return 1;
}
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==-1)
{
perror("cannot connect to the server");
close(connect_fd);
return 1;
}
memset(snd_buf,0,1024);
strcpy(snd_buf,"message from client");
//send info server
for(i=0;i<4;i++)
write(connect_fd,snd_buf,sizeof(snd_buf));
close(connect_fd);
return 0;
}

编译运行:

[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]#
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
一个人很有钱现在跟你说手头紧怎么回 一个人怎么总是手头很紧 左右手紧紧扣到一起,抓得很紧是什么心里? 上班路上摔伤是否构成工伤 阿里云盘TV版播放不了怎么办?第三方阿里云盘播放异常怎么解决? 阿里云盘怎么转到百度网盘 阿里云盘转移资源到百度网盘方法 类风湿性关节炎常见的临床表现有哪些 试用期不给签合同吗 发生车祸了对方全责怎么赔偿 6岁孩子背声律启蒙有用吗 相对于地面通信方式,卫星通信有哪些特点? 兄弟2820 一体机 没粉了 是换TN2050的粉盒 还是换DR2050的鼓架呢 相对于地面参照系摆球的机械能是否保持不变 火箭起飞后,火箭相对于地面是 “我的航天梦”手抄报的句子有什么? 兄弟2050加什么粉 静坐在教室里的同学 相对于地面而言是静止的吗 兄弟一体机2050,打印测试页出纸,但是纸上什么也没有,该怎么处理 若人相对于地面匀速运动说明什么? UNIX域套接字的sun_path文件创建时怎么从/tmp下改到当前文件夹? 人在路上行走相对于地面是运动还是静止? 物理题中经常说,。。。相对地面是运动或是静止,相对地面是什么意思 如果不能,怎么才能重复利用这个套接字 相对于地面,没有改变位置的物体是绝对静止的是对的还是错的? socket unix域协议怎样和ipv4协议通信 兄弟2050硒鼓和2150硒鼓有什么不同? 怎么查看unix域套接字的连接状态 怎么到日照开发区卫生局 保定周边口罩厂还有招工的吗? 2014年山东日照莒县卫生事业单位考试职位表下载报考时间 求一本异能小说。是写一个人兄弟反目,被妖狐附体,智商到了200多,背景时间好像是2050年左右 人相对于地面的速度 人走路时为什么相对于地面是静止的 地球同步卫星相对于地面是静止的吗 人造地球同步卫星相对于地面是___的,相对于太阳,它是___的 传送带相对于地面是运动 木块A相对于地面不是运动的吗。为什么题目的答案说是静止的 判断题 如物体相对于地面保持静止或匀速运动状态,则物体处于平衡。 大口吃瓜,快意飞马猜一动物 物理中,人在原地起立和蹲下,相对于地面来说,是运动的吗? 青岛快意飞马发制品有限公司怎么样? 班梁列传全文翻译,速度急着用,有悬赏 快意飞马 什么意思 天津哪有机电一体化不错点的学校? 谢菲的个人简历 可以帮我制作一个中秋节带音乐的电子贺卡吗? 房地产公司如何签订劳动合同 最近身体不太好,特别是指甲和消化。。。 冬天坐办公室吹着空调,腰部以下都是冰的怎么办?手、脸肤色一到下午就变黄,满脸油光,而且指甲有棱。 皮肤非常油,洗脸一个月用指甲一刮就是一层油,脸上看着也非常脏,油光满面,用了好多方法换没有效果,怎