Socket编程实现简单的本地套接字通信

1 本地套接字

1.1 注意事项

  1. 创建Socket套接字时传递的参数与网络套接字不同,域参数应该是AF_LOCAL或者AF_UNIX,而不能用AF_INET之类。
  2. 不同于网络套接字的绑定,本地套接字绑定的是struct sockaddr_un结构。
  3. 客户端在连接前同样需要绑定本地套接字,并且填充服务端sockaddr_un地址结构,然后再进行connect。
  4. 在通信结束后,需要删除套接字文件后才能再次运行,可使用unlink()函数在程序运行开始时删除相应文件。

1.2 sockaddr_un结构体

#include <sys/un.h>
struct sockaddr_un {
	sa_family_t sun_family;       //AF_LOCAL/AF_UNIX
	char sun_path[UNIX_PATH_MAX]; // 套接字文件的路径, 伪文件, 大小为0
};

2 程序示例

2.1 服务端程序

#include <iostream>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#include <string.h>

#define MAX_CONN 1024

using namespace std;

int main() {
    int lfd, cfd;
    sockaddr_un addr, caddr;
    socklen_t len =sizeof(caddr);

    unlink("server.sock");

    if((lfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(-1);
    }

    addr.sun_family = AF_LOCAL;
    strcpy(addr.sun_path, "server.sock");
    if(bind(lfd, (sockaddr *)&addr, sizeof(addr)) == -1) {
        perror("bind");
        exit(-1);
    }

    listen(lfd, MAX_CONN);

    if((cfd = accept(lfd, (sockaddr *)&caddr, &len)) == -1) {
        perror("accept");
        exit(-1);
    }
    
    while(1) {
        char buf[1024];
        int len = recv(cfd, buf, sizeof(buf), 0);
        if(len == -1) {
            perror("recv");
            exit(-1);
        }
        else if(len == 0) {
            cout << "(SERVER) client closed..." << endl;
            break;
        }
        else if(len > 0) {
            cout << "(SERVER) recv : " << buf << endl;
            send(cfd, buf, len ,0);
        }
    }
    
    close(cfd);
    close(lfd);

    return 0;
}

2.2 客户端程序

#include <iostream>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#include <string.h>

#define MAX_CONN 1024

using namespace std;

int main() {
    int cfd;
    sockaddr_un addr, saddr;

    unlink("client.sock");

    if((cfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(-1);
    }

    addr.sun_family = AF_LOCAL;
    strcpy(addr.sun_path, "client.sock");
    //绑定本地套接字
    if(bind(cfd, (sockaddr *)&addr, sizeof(addr)) == -1) {
        perror("bind");
        exit(-1);
    }

    //连接服务器
    saddr.sun_family = AF_LOCAL;
    strcpy(saddr.sun_path, "server.sock");
    if(connect(cfd, (sockaddr *)&saddr, sizeof(saddr)) == -1) {
        perror("connect");
        exit(-1);
    }
    
    int num = 0;
    while(1) {
        char buf[1024];
        sprintf(buf, "i am client : %d\n", num++);
        send(cfd, buf, strlen(buf) + 1, 0);
        int len = recv(cfd, buf, sizeof(buf), 0);
        if(len == -1) {
            perror("recv");
            exit(-1);
        }
        else if(len == 0) {
            cout << "(CLIENT) server closed..." << endl;
            break;
        }
        else if(len > 0) {
            cout << "(CLIENT) recv : " << buf << endl;
        }
        sleep(1);
    }    
    close(cfd);
    return 0;
}

2.3 运行结果

在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值