ndk学习16: unix domain socket

一、UNIX Domain Socket

概念:

UNIX Domain Socket是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC)

特点:

1. 它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等

2. 只是将应用层数据从一个进程拷贝到另一个进程。

工作模式:

SOCK_DGRAM     类似于UDP

SOCK_STREAM    类似于TCP

用途:

UNIX Domain Socket可用于两个没有亲缘关系的进程,是全双工的,是目前使用最广泛的IPC机制

比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的

二、工作流程

与网络socket的不同点:

1.  address family为AF_UNIX

2.  unix domain socket不需要IP和端口,取而代之的是文件路径来表示“网络地址”

            原理:

UNIXDomain socket用结构体sockaddr_un表示,是一个socket类型的文件在文件系统中的路径

这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回

UNIX Domain Socket客户端一般要显式调用bind函数,而不象网络socket一样依赖系统自动分配的地址。

客户端bind的socket文件名可以包含客户端的pid,这样服务器就可以区分不同的客户端

工作流程:

服务器端:创建socket—绑定文件(端口)—监听—接受客户端连接—接收/发送数据—…—关闭

客户端:   创建socket—绑定文件(端口)—连接—发送/接收数据—…—关闭

三、阻塞和非阻塞(SOCK_STREAM方式)

读写操作有两种操作方式:阻塞和非阻塞

1.阻塞模式下

阻塞模式下,发送数据方和接收数据方的表现情况如同命名管道

2.非阻塞模式

在send或recv函数的标志参数中设置MSG_DONTWAIT,则发送和接收都会返回。如果没有成功,则返回值为-1,errno为EAGAIN 或 EWOULDBLOCK

四.实例

服务端代码:

#include <stdio.h>

#include <sys/stat.h>

#include <sys/socket.h>

#include <sys/un.h>

#include <errno.h>

#include <stddef.h>

#include <string.h>

#include <unistd.h>

#include <time.h>

#include <stdlib.h>

#define UNIX_DOMAIN "/data/local/tmp/ndk_cmd"

int main(void) {

int listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);

if (listen_fd < 0) {

perror("cannot create communication socket\n");

return 1;

}

//set server addr_param

struct sockaddr_un srv_addr;

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

int 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

struct sockaddr_un clt_addr;

int len = sizeof(clt_addr);

int 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");

static char recv_buf[1024];

for (int 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;

}

客户端代码:

#include <stdio.h>

#include <stddef.h>

#include <sys/stat.h>

#include <sys/socket.h>

#include <sys/un.h>

#include <errno.h>

#include <string.h>

#include <unistd.h>

#include <time.h>

#include <stdlib.h>

int main(void) {

//creat unix socket

int connect_fd = socket(PF_UNIX, SOCK_STREAM, 0);

if (connect_fd < 0) {

perror("cannot create communication socket");

return 1;

}

static struct sockaddr_un srv_addr;

srv_addr.sun_family = AF_UNIX;

strcpy(srv_addr.sun_path, "/data/local/tmp/ndk_cmd");

//connect server

int 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;

}

char snd_buf[1024];

memset(snd_buf, 0, 1024);

strcpy(snd_buf, "message from client");

//send info server

for (int i = 0; i < 4; i++)

write(connect_fd, snd_buf, sizeof(snd_buf));

close(connect_fd);

return 0;

}

运行结果:

来自为知笔记(Wiz)

时间: 2024-12-26 03:32:51

ndk学习16: unix domain socket的相关文章

由一个简单需求到Linux环境下的syslog、unix domain socket

本文记录了因为一个简单的日志需求,继而对linux环境下syslog.rsyslog.unix domain socket的学习.本文关注使用层面,并不涉及rsyslog的实现原理,感兴趣的读者可以参考rsyslog官网.另外,本文实验的环境实在debian8,如果是其他linux发行版本或者debian的其他版本,可能会稍微有些差异. 需求: 工作中有一个在Linux(debian8)环境下运行的服务器程序,用python语言实现,代码中有不同优先级的日志需要记录,开发的时候都是使用pytho

unix domain socket示例一(SOCK_DGRAM)

unix domain socket 是IPC通信的一种方式,可用于与管理进程间通信,同时由和网络socket统一,所以很好管理,使用还是比较多.现举个例子: server.c 1 #include <stdio.h> 2 #include <string.h> 3 #include <unistd.h> 4 #include <stdlib.h> 5 #include <sys/types.h> 6 #include <sys/socke

UNIX DOMAIN SOCKET效率

关于UNIX DOMAIN SOCKET和普通udp socket的对比 在TX1(4核A57 1.7GHz)的板卡上进行测试,每个包大小设置为1024,全速收发,UDS的速度在90Mbps左右,UDP在120Mbps左右(略有丢包) CPU占用率,UDS比UDP低10%,但是实际上,如果码率相近时,CPU占用率是差不多的 下面是UDP的CPU占用: top - 08:44:46 up 3:04, 5 users, load average: 1.78, 1.70, 1.66 Threads:

UNIX Domain Socket IPC

目录 目录 概述 socket函数使用 struct sockaddr_un socket bind listen accept connect Socket IPC 实例 server client 运行结果 概述 socket API原本是为网络通讯设计的,但是后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket. 虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于

问题解决:psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket &quot;/var/run/postgresql/.s.PGSQL.5432&quot;?

错误提示: psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"? 出现该问题的很多,以下是目前碰到的几种情况,之后碰到继续补充: 1.删除了/tmp路径中的.s.PGSQL.5432 与.s.

【转】PHP实现系统编程(四)--- 本地套接字(Unix Domain Socket)

原文:http://blog.csdn.net/zhang197093/article/details/78143687?locationNum=6&fps=1 -------------------------------------------------------------------------------------------------------------------------------------------------------- Socket API一开始是为了

[dev][socket] unix domain socket删除socket文件

问题 在使用unix domain socket的时候,bind之后,会在本地路径里 产生一个与path对应的socket文件. 如何正确的在用完socket之后,对其销毁呢? 方案 使用 unlink()函数手工删除. 见: https://stackoverflow.com/questions/34873151/how-can-i-delete-a-unix-domain-socket-file-when-i-exit-my-application syslogd的代码里就是这样干的: ht

Unix domain socket

Unix domain socket 原文:https://www.cnblogs.com/sparkdev/p/8359028.html UNIX Domain Socket是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC),它不需要经过网络协议栈,不需要打包拆包.计算校验和.维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程.UNIX Domain Socket有SOCK_DGRAM或SOCK_STREAM两种工作模式,类似于UDP和TCP,但是面向消息的UNIX

redis性能测试tcp socket and unix domain

UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包.计算校验和.维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程.UNIX域套接字与TCP套接字相比较,在同一台主