网络编程(33)—— 使用AF_UNIX构建本地通信的socket服务端和客户端

        之前一直使用AF_INET构造socket服务端和客户端,本文介绍下使用AF_UNIX构建本地通信的socket服务端和客户端。我们先列出代码,然后在对代码进行分析:

服务端:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<string.h>
#include<sys/un.h>//头文件发生了变化
#define BUF_SIZE 1024
 
void error_handling(const char* message);
int main()
{
   int serv_sock,clnt_sock;
     //采用的地址结构体不再是sockaddr_in,而是sockaddr_un
   struct sockaddr_un serv_addr,clnt_addr;
   int  clnt_addr_sz,str_len;
    char buf[BUF_SIZE];
   char * path="sock";
                   //创建socket时,协议族改为AF_UNIX
   serv_sock=socket(AF_UNIX,SOCK_STREAM,0);
   //填写的地址信息发生变化,没有了IP地址和端口号而是通过本地文件为媒介进行通信
   serv_addr.sun_family=AF_UNIX;
   strncpy(serv_addr.sun_path,path,strlen(path));
 
   if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1)
       error_handling("bind() error");
 
   if(listen(serv_sock,1)==-1)
       error_handling("listen() error");
   
   clnt_addr_sz=sizeof(clnt_addr);
   if((clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_sz))==-1)
       error_handling("accept() error");
   
   while(1)
    {
       str_len = read(clnt_sock,buf,BUF_SIZE);
       if(str_len<=0)
           break;
       write(clnt_sock,buf,str_len);
    }
 
   close(clnt_sock);
   close(serv_sock);  
   return 0;
}
void error_handling(const char* message)
{
   fputs(message,stderr);
   fputc('\n',stderr);
   exit(1);
}

客户端:

#include<stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<string.h>
#define BUF_SIZE 1024

int main()
{
    int sock;
    struct sockaddr_un addr;
    int str_len;
    char buf[BUF_SIZE];
    char* path="sock";
    sock=socket(AF_UNIX,SOCK_STREAM,0);

    addr.sun_family=AF_UNIX;
    strncpy(addr.sun_path,path,strlen(path));
    
    connect(sock,(struct sockadd*)&addr,sizeof(addr));

    while(1)
    {
        fputs("input:",stdout);
        fgets(buf,BUF_SIZE,stdin);
        if(!strcmp(buf,"q\n")||!strcmp(buf,"Q\n"))
            break;
        write(sock,buf,BUF_SIZE);
        str_len=read(sock,buf,BUF_SIZE-1);
        buf[str_len]=0;
        printf("the message from serv:%s\n",buf);

    }
    close(sock);
    return 0;
}

        以上是一个socket本地回声服务端和客户端的代码,从代码上也可以看出,是通过一个本地文件sock来实现和客户端进行通信的,本质上其实就是进程间的通信,和之前网络通信的服务端相比,主要有以下改动:
1、创建的socket协议族不同,创建网络通信的socket时我们用的AF_INET,而创建本地通信的socket时用的协议族是AF_UNIX。
2、使用的地址不同,主要表现在:
(1)头文件不同,本地通信使用的是sys/un.h头文件
(2)地址结构体不同,本地通信使用struct sockaddr_un
(3)地址的赋值不同,分别使用struct sockaddr_un的sun_family成员存储协议族信息,sun_path成员存储用于通信的中间文件。
        其实除了以上节点和网络通信的区别之外,其他基本相同。
        另外需要注意的是,进行本地通信时,我们定义了一个本地通信的中间文件sock,但是实际上每次连接,程序都会通过将sock重命名的方式生成另外的文件,也就是说每次连接的中间文件都会不同,请看下图中,红色圈出部分,我进行了三次连接,就出现了三个以sock开头的文件。


Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
Git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL33

























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值