linux 共享内存 unix域,Unix域套接字:在一个服务器进程和多个客户进程之间使用数据报通信...

有一个诀窍使用UNIX数据报套接字。与流套接字(tcp或unix域)不同,数据报套接字需要为服务器和客户端定义的端点。当在流套接字中建立连接时,操作系统隐式创建客户端的端点。无论这是对应于短暂的TCP/UDP端口还是临时的unix域inode,客户端都是为您创建的。这就是为什么你通常不需要为客户端的流套接字发出bind()调用。

您看到“地址已被使用”的原因是您要告诉客户端绑定到与服务器相同的地址。 bind()是关于断言外部身份。两个套接字通常不能具有相同的名称。

数据报套接字,特别是Unix域数据报套接字,客户端必须bind()其自己端点,然后connect()到服务器的端点。这是您的客户端代码,稍加修改,在投入了一些其他东西:

char * server_filename = "/tmp/socket-server";

char * client_filename = "/tmp/socket-client";

struct sockaddr_un server_addr;

struct sockaddr_un client_addr;

memset(&server_addr, 0, sizeof(server_addr));

server_addr.sun_family = AF_UNIX;

strncpy(server_addr.sun_path, server_filename, 104); // XXX: should be limited to about 104 characters, system dependent

memset(&client_addr, 0, sizeof(client_addr));

client_addr.sun_family = AF_UNIX;

strncpy(client_addr.sun_path, client_filename, 104);

// get socket

int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);

// bind client to client_filename

bind(sockfd, (struct sockaddr *) &client_addr, sizeof(client_addr));

// connect client to server_filename

connect(sockfd, (struct sockaddr *) &server_addr, sizeof(server_addr));

...

char buf[1024];

int bytes = read(sockfd, buf, sizeof(buf));

...

close(sockfd);

此时你的插座应充分建立。我认为理论上你可以使用read()/write(),但通常我会使用send()/recv()作为数据报套接字。

通常情况下,您需要在每个通话后检查错误,然后发出perror()。当事情出错时,它将极大地帮助你。一般来说,使用这样的模式:

if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {

perror("socket failed");

}

这几乎适用于任何C系统调用。

最好的参考是Steven的“Unix网络编程”。在第3版中,第15.4节第415-419页显示了一些示例并列出了许多注意事项。

顺便说一句,在参考

我想这是因为没有接收进程正在听这地方插座,是否正确?

我认为你是正确的从服务器中的write() ENOTCONN错误。 UDP套接字通常不会抱怨,因为它无法知道客户端进程是否正在侦听。但是,unix域数据报套接字是不同的。实际上,如果客户端的接收缓冲区已满而不是丢弃数据包,write()实际上会阻塞。这使得unix域数据报套接字远远优于IPC的UDP,因为在加载时UDP甚至会在本地主机上确实会丢弃数据包。另一方面,这意味着你必须小心快速的作家和慢读者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值