10 UNIX域协议

UNIX域套接字地址结构

#include <sys/un.h>
struct sockaddr_un {
    sa_family sun_family;
    char sun_path[104];
}


套接字函数

1、路径最好是绝对路径,不要相对路径;

2、和connect调用中指定的路径名必须是一个当前绑定在某个打开的UNIX域套接字上的路径名,而且他们的套接字类型(字节流或数据报)也必须一致;

3、在一个未绑定的Unix域套接字上发送数据报不会自动给这个套接字捆绑一个路径名,这点不同于UDP套接字(对于UDP套接字,会自动绑定一个临时端口),所以对于数据报UNIX域套接字客户端,则必须调用bind。


UNIX域字节流客户端/服务端

客户端:

#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /*for struct sockaddr_in*/

#define PATH "/home/unix_sock_xxxxx"
#define MAX_BUF_LEN 255

int main() {
    int sockfd = 0;
    sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);

    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(struct sockaddr_un));
    addr.sun_family = AF_LOCAL;
    strncpy(addr.sun_path, PATH, sizeof(addr.sun_path) - 1);
    
    connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    printf("client is on...\n");  
   
    int i = 0;  
    for (i = 0; i < 5; i++)  
    {  
        char * msg = "hello server....";  
        printf("client send msg: %s\n", msg);  
        if((send(sockfd, msg, strlen(msg), 0))<0)  
        {  
            perror("send()");  
        }  
    
        char recv_buf[MAX_BUF_LEN] = {0};  
        int recv_len = recv(sockfd, recv_buf, sizeof(recv_buf), 0);  
        printf("client recv msg: %s\n", recv_buf);    
    } 
    return 1;
}

服务端:

#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /*for struct sockaddr_in*/

#define PATH "/home/unix_sock_xxxxx"
#define BACKLOG   10  
#define MAX_BUF_LEN 255

int main() {
    int listenfd = 0;
    int connfd   = 0;
    struct sockaddr_un svr_addr;
    struct sockaddr_un cli_addr;
    memset(&svr_addr, 0, sizeof(struct sockaddr_un));
    memset(&cli_addr, 0, sizeof(struct sockaddr_un));

    listenfd = socket(AF_LOCAL, SOCK_STREAM, 0);

    unlink(PATH);
    svr_addr.sun_family = AF_LOCAL;
    strncpy(svr_addr.sun_path, PATH, sizeof(svr_addr.sun_path) - 1);
    
    bind(listenfd, (struct sockaddr*)&svr_addr, SUN_LEN(&svr_addr));
    listen(listenfd, BACKLOG);
    printf("server is on...\n");  
    
    int cli_len = sizeof(cli_addr);
    connfd = accept(listenfd, (struct sockaddr*)&cli_addr, &cli_len);
    
    char recv_buf[MAX_BUF_LEN] = {0};  
    int recv_len = 0;
    while((recv_len = recv(connfd, recv_buf, sizeof(recv_buf), 0)) > 0)  
    {  
        printf("svr %d recv %s recv_len %d\n", connfd, recv_buf, recv_len);  
        int ret = send(connfd, recv_buf, strlen(recv_buf), 0);  
        if (ret < 0)  
        {  
            perror("send failed");  
            exit(1);  
        }  
        memset(recv_buf, 0, sizeof(recv_buf));  
    }  
    
    return 1;
}

总结:和普通tcp套接字相比,不同点有family为AF_LOCAL,地址类型为sockaddr_un,同时宏SUN_LEN返回的是不包括空字符的结构体长度。其它基本一样。




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值