加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

Unix domain socket 简介

发布时间:2020-12-13 14:11:40 所属栏目:Linux 来源:网络整理
导读:Unix domain socket 又叫 IPC(inter-process communication 进程间通信) socket,用于实现同一主机上的进程间通信。 socket 原本是为网络通讯设计的,但后来在 socket 的框架上发展出一种 IPC 机制,就是 UNIX domain socket。虽然网络 socket 也可用于同一

Unix domain socket 又叫 IPC(inter-process communication 进程间通信) socket,用于实现同一主机上的进程间通信。socket 原本是为网络通讯设计的,但后来在 socket 的框架上发展出一种 IPC 机制,就是 UNIX domain socket。虽然网络 socket 也可用于同一台主机的进程间通讯(通过 loopback 地址 127.0.0.1),但是 UNIX domain socket 用于 IPC 更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC 机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。

#include <.h>

<span style="color: #0000ff">#define MAXLINE 80

<span style="color: #0000ff">char *socket_path = <span style="color: #800000">"<span style="color: #800000">server.socket<span style="color: #800000">"<span style="color: #000000">;

<span style="color: #0000ff">int main(<span style="color: #0000ff">void<span style="color: #000000">)
{
<span style="color: #0000ff">struct<span style="color: #000000"> sockaddr_un serun,cliun;
socklen_t cliun_len;
<span style="color: #0000ff">int<span style="color: #000000"> listenfd,connfd,size;
<span style="color: #0000ff">char<span style="color: #000000"> buf[MAXLINE];
<span style="color: #0000ff">int<span style="color: #000000"> i,n;

</span><span style="color: #0000ff"&gt;if</span> ((listenfd = socket(AF_UNIX,SOCK_STREAM,<span style="color: #800080"&gt;0</span>)) < <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;) {  
    perror(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;socket error</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  
    exit(</span><span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;);  
}  

memset(</span>&amp;serun,<span style="color: #800080"&gt;0</span>,<span style="color: #0000ff"&gt;sizeof</span><span style="color: #000000"&gt;(serun));  
serun.sun_family </span>=<span style="color: #000000"&gt; AF_UNIX;  
strcpy(serun.sun_path,socket_path);  
size </span>= offsetof(<span style="color: #0000ff"&gt;struct</span> sockaddr_un,sun_path) +<span style="color: #000000"&gt; strlen(serun.sun_path);  
unlink(socket_path);  
</span><span style="color: #0000ff"&gt;if</span> (bind(listenfd,(<span style="color: #0000ff"&gt;struct</span> sockaddr *)&amp;serun,size) < <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;) {  
    perror(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;bind error</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  
    exit(</span><span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;);  
}  
printf(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;UNIX domain socket boundn</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  

</span><span style="color: #0000ff"&gt;if</span> (listen(listenfd,<span style="color: #800080"&gt;20</span>) < <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;) {  
    perror(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;listen error</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  
    exit(</span><span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;);          
}  
printf(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;Accepting connections ...n</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  

</span><span style="color: #0000ff"&gt;while</span>(<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;) {  
    cliun_len </span>= <span style="color: #0000ff"&gt;sizeof</span><span style="color: #000000"&gt;(cliun);         
    </span><span style="color: #0000ff"&gt;if</span> ((connfd = accept(listenfd,(<span style="color: #0000ff"&gt;struct</span> sockaddr *)&amp;cliun,&amp;cliun_len)) < <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;){  
        perror(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;accept error</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  
        </span><span style="color: #0000ff"&gt;continue</span><span style="color: #000000"&gt;;  
    }  

    </span><span style="color: #0000ff"&gt;while</span>(<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;) {  
        n </span>= read(connfd,buf,<span style="color: #0000ff"&gt;sizeof</span><span style="color: #000000"&gt;(buf));  
        </span><span style="color: #0000ff"&gt;if</span> (n < <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;) {  
            perror(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;read error</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  
            </span><span style="color: #0000ff"&gt;break</span><span style="color: #000000"&gt;;  
        } </span><span style="color: #0000ff"&gt;else</span> <span style="color: #0000ff"&gt;if</span>(n == <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;) {  
            printf(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;EOFn</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  
            </span><span style="color: #0000ff"&gt;break</span><span style="color: #000000"&gt;;  
        }  

        printf(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;received: %s</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;,buf);  

        </span><span style="color: #0000ff"&gt;for</span>(i = <span style="color: #800080"&gt;0</span>; i < n; i++<span style="color: #000000"&gt;) {  
            buf[i] </span>=<span style="color: #000000"&gt; toupper(buf[i]);  
        }  
        write(connfd,n);  
    }  
    close(connfd);  
}  
close(listenfd);  
</span><span style="color: #0000ff"&gt;return</span> <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;;  

}

socket( family, type, protocol);

family 指定为 AF_UNIX,使用 AF_UNIX 会在系统上创建一个 socket 文件,不同进程通过读写这个文件来实现通信。type 可以选择 SOCK_DGRAM 或 SOCK_STREAM。SOCK_STREAM 意味着会提供按顺序的、可靠、双向、面向连接的比特流。SOCK_DGRAM 意味着会提供定长的、不可靠、无连接的通信。protocol 参数指定为 0 即可。

#include <.h>

<span style="color: #0000ff">#define MAXLINE 80

<span style="color: #0000ff">char client_path = <span style="color: #800000">"<span style="color: #800000">client.socket<span style="color: #800000">"<span style="color: #000000">;
<span style="color: #0000ff">char
server_path = <span style="color: #800000">"<span style="color: #800000">server.socket<span style="color: #800000">"<span style="color: #000000">;

<span style="color: #0000ff">int<span style="color: #000000"> main() {
<span style="color: #0000ff">struct<span style="color: #000000"> sockaddr_un cliun,serun;
<span style="color: #0000ff">int<span style="color: #000000"> len;
<span style="color: #0000ff">char buf[<span style="color: #800080">100<span style="color: #000000">];
<span style="color: #0000ff">int<span style="color: #000000"> sockfd,n;

</span><span style="color: #0000ff"&gt;if</span> ((sockfd = socket(AF_UNIX,<span style="color: #800080"&gt;0</span>)) < <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;){  
    perror(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;client socket error</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  
    exit(</span><span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;);  
}  

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 一般显式调用bind函数,以便服务器区分不同客户端  </span>
memset(&amp;cliun,<span style="color: #0000ff"&gt;sizeof</span><span style="color: #000000"&gt;(cliun));  
cliun.sun_family </span>=<span style="color: #000000"&gt; AF_UNIX;  
strcpy(cliun.sun_path,client_path);  
len </span>= offsetof(<span style="color: #0000ff"&gt;struct</span> sockaddr_un,sun_path) +<span style="color: #000000"&gt; strlen(cliun.sun_path);  
unlink(cliun.sun_path);  
</span><span style="color: #0000ff"&gt;if</span> (bind(sockfd,len) < <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;) {  
    perror(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;bind error</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  
    exit(</span><span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;);  
}  

memset(</span>&amp;serun,server_path);  
len </span>= offsetof(<span style="color: #0000ff"&gt;struct</span> sockaddr_un,sun_path) +<span style="color: #000000"&gt; strlen(serun.sun_path);  
</span><span style="color: #0000ff"&gt;if</span> (connect(sockfd,len) < <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;){  
    perror(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;connect error</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);  
    exit(</span><span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;);  
}  

</span><span style="color: #0000ff"&gt;while</span>(fgets(buf,MAXLINE,stdin) !=<span style="color: #000000"&gt; NULL) {    
     write(sockfd,strlen(buf));    
     n </span>=<span style="color: #000000"&gt; read(sockfd,MAXLINE);    
     </span><span style="color: #0000ff"&gt;if</span> ( n < <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt; ) {    
        printf(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;the other side has been closed.n</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);    
     }</span><span style="color: #0000ff"&gt;else</span><span style="color: #000000"&gt; {    
        write(STDOUT_FILENO,n);    
     }    
}   
close(sockfd);  
</span><span style="color: #0000ff"&gt;return</span> <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;;  

}

$ server.c - client.c -o client

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读