[转帖]UNIX SOCKET简介

unix,socket,简介 · 浏览次数 : 0

小编点评

**UNIX Domain Socket** **介绍** UNIX Domain Socket是用于同一台主机的进程间通信的可靠性通信机制。它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序列号应答。 **主要特点** * 非阻塞性通信:允许应用程序接收多个连接的处理。 * 可靠性:通过检查连接状态和错误处理机制确保连接正常。 * 可扩展性:可以创建多个连接并处理多个连接的请求。 **用法** 1. 创建套件。 2. 指定套件类型和地址。 3. 设置超时时间。 4. 建立连接。 5. 发送和接收数据。 6. 关闭连接。 **示例** ```c #include #include #include #include #include int main() { // Create a socket int sock_fd = socket(AF_INET, SOCK_STREAM, 0); // Set socket options int optval = 1; setsockopt(sock_fd, SOL_SOCKET, &optval, sizeof(optval)); // Bind socket to address struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(80); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); int bind_res = bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr)); // Listen for incoming connections int listen_res = listen(sock_fd, 10, (struct sockaddr *)NULL); // Accept incoming connection struct sockaddr_in client_addr; socklen_t client_len; client_len = sizeof(client_addr); int new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &client_len); // Send data to client char buffer[] = "Hello from server!"; int sent_res = send(new_fd, buffer, sizeof(buffer), 0); // Close client socket close(new_fd); // Close server socket close(sock_fd); return 0; } ``` **结果** 该程序将创建一个套件,绑定到指定地址和端口,并监听来自 127.0.0.1 的连接。当有连接时,程序将接收数据并将其打印到终端上。

正文

      UNIX Domain SOCKET 是在Socket架构上发展起来的用于同一台主机的进程间通讯(IPC)。它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序列号应答等。只是将应用层数据从一个进程拷贝到另一个进程。UNIX Domain SOCKET有SOKCET_DGRAM和SOCKET_STREAM两种模式,类似于UDP和TCP,但是面向消息的UNIX socket也是可靠的,消息既不会丢失也不会顺序错乱。

 

     UNIX Domain Socket是全双工的,API接口语义丰富,相比其它IPC机制有明显的优越性,目前已成为使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的。

使用UNIX Domain Socket的过程和网络socket十分相似,也要先调用socket()创建一个socket文件描述符,address family指定为AF_UNIX,type可以选择SOCK_DGRAM或SOCK_STREAM,protocol参数仍然指定为0即可。

     UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。

服务端: socket -> bind -> listen -> accept -> recv/send -> close 
客户端: socket -> connect -> recv/send -> close

  • 开始创建socket
  1. int socket(int domain, int type, int protocol)
  2. domain(域) : AF_UNIX
  3. type : SOCK_STREAM/ SOCK_DGRAM :
  4. protocol : 0

SOCK_STREAM(流) : 提供有序,可靠的双向连接字节流。 可以支持带外数据传输机制, 
无论多大的数据都不会截断 
SOCK_DGRAM(数据报):支持数据报(固定最大长度的无连接,不可靠的消息),数据报超过最大长度,会被截断.

获取到socket文件描述符之后,还要将其绑定一个文件上
 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd : 传入sock的文件描述符
addr : 用sockaddr_un表示
addrlen : 结构体长度

struct sockaddr_un {
    sa_family_t sun_family; /* AF_UNIX */
    char sun_path[UNIX_PATH_MAX];   /* pathname */
};

监听客户端的连接
int listen(int sockfd, int backlog);
sockfd : 文件描述符
backlog : 连接队列的长度

接受客户端的连接
int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);
Unux domain socket不存在客户端地址的问题,因此这里的addr和addrlen参数可以设置为NULL
 

server 端程序:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/un.h>
#include<errno.h>
#include<stddef.h>
#include<unistd.h>

#define MAX_CONNECT_NUM 2
#define BUFFER_SIZE 1024
const char *filename="uds-tmp";

int main()
{
    int fd,new_fd,len,i;
    struct sockaddr_un un;
    fd = socket(AF_UNIX,SOCK_STREAM,0);
    if(fd < 0){
        printf("Request socket failed!\n");
        return -1;
    }
    un.sun_family = AF_UNIX;
    unlink(filename);
    strcpy(un.sun_path,filename);
    if(bind(fd,(struct sockaddr *)&un,sizeof(un)) <0 ){
        printf("bind failed!\n");
        return -1;
    }
    if(listen(fd,MAX_CONNECT_NUM) < 0){
        printf("listen failed!\n");
        return -1;
    }
    while(1){
        struct sockaddr_un client_addr;
        char buffer[BUFFER_SIZE];
        bzero(buffer,BUFFER_SIZE);
        len = sizeof(client_addr);
        //new_fd = accept(fd,(struct sockaddr *)&client_addr,&len);
        new_fd = accept(fd,NULL,NULL);
        if(new_fd < 0){
            printf("accept failed\n");
            return -1;
        }
        int ret = recv(new_fd,buffer,BUFFER_SIZE,0);
        if(ret < 0){
            printf("recv failed\n");
        }
        for(i=0; i<10; i++){
            printf(" %d",buffer[i]);
        }
        close(new_fd);
        break;
    }
    close(fd);
}
 

client 端程序:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/un.h>
#include<errno.h>
#include<stddef.h>
#include<unistd.h>
#define BUFFER_SIZE 1024
const char *filename="uds-tmp";

int main()
{
    struct sockaddr_un un;
    int sock_fd;
    char buffer[BUFFER_SIZE] = {1,2,3};
    un.sun_family = AF_UNIX;
    strcpy(un.sun_path,filename);
    sock_fd = socket(AF_UNIX,SOCK_STREAM,0);
    if(sock_fd < 0){
        printf("Request socket failed\n");
        return -1;
    }
    if(connect(sock_fd,(struct sockaddr *)&un,sizeof(un)) < 0){
        printf("connect socket failed\n");
        return -1;
    }
    send(sock_fd,buffer,BUFFER_SIZE,0);

    close(sock_fd);
    return 0;
}
 

 

 

与[转帖]UNIX SOCKET简介相似的内容:

[转帖]UNIX SOCKET简介

UNIX Domain SOCKET 是在Socket架构上发展起来的用于同一台主机的进程间通讯(IPC)。它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序列号应答等。只是将应用层数据从一个进程拷贝到另一个进程。UNIX Domain SOCKET有SOKCET_DGRAM和SOCKET_

[转帖]Unix Domain Socket– IPC通信机制

什么是Unix Domain Socket 基于socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC 更有效率 : 不需

[转帖]AF_UNIX 本地通信

文章目录 一、AF_UNIX 本地通信1. Linux进程通信机制2. socket本地域套接字AF_UNIX3. demo示例 二、AF_INET域与AF_UNIX域socket通信原理对比1. AF_INET域socket通信过程2. AF_UNIX域socket通信过程3. 相同点4. 不同点

[转帖]MySQL Performance : IP port -vs- UNIX socket impact in 8.0 GA

http://dimitrik.free.fr/blog/posts/mysql-performance-80-ga-ip-port-vs-unix-socket-impact.html 2018-06-15 16:05 | MySQL, Performance, InnoDB, Benchmark

[转帖]这种本机网络 IO 方法,性能可以翻倍!

https://www.bilibili.com/read/cv16902163?spm_id_from=333.999.0.0 大家好,我是飞哥! 很多读者在看完《127.0.0.1 之本机网络通信过程知多少 ?》这一篇后,让我讲讲 Unix Domain Socket。好了,今天就安排! 在本机

[转帖]How fast are Unix domain sockets?

https://blog.myhro.info/2017/01/how-fast-are-unix-domain-sockets Jan 3, 2017 • Tiago Ilieve Warning: this is my first post written in English, after o

[转帖]Unix 已落幕,Unix 仍长存

https://linux.cn/article-15457-1.html 不要指望再看到任何更多的 AIX 大新闻了。这意味着最后剩下的 Unix 是 …… Linux。 这是一个时代的结束。正如上周报道的那样,IBM 已经将 AIX 的开发转移到印度。在它支付了 340 亿美金买下了红帽,有了自

[转帖]Unix is dead. Long live Unix!

https://www.theregister.com/2023/01/17/unix_is_dead/ Don't expect to see any more big AIX news. What does that leave us with? Liam Proven Tue 17 Jan 2

[转帖]AF_UNIX和AF_INET

https://www.cnblogs.com/shangerzhong/p/9153737.html family参数代表地址家族,比较常用的为AF_INET或AF_UNIX。AF_UNIX用于同一台机器上的进程间通信,AF_INET对于IPV4协议的TCP和UDP 。 type参数代表套接字类型

[转帖]Linux 与 Unix 到底有什么不同?

https://www.oschina.net/translate/differences-between-linux-and-unix?print 如果你是一名20多岁或30多岁的软件开发人员,那么你已成长在一个由Linux主导的世界中。数十年来,它一直是数据中心的重要参与者,尽管很难找到明确的操