关于本地套接字的使用

简述:
本地套接字的使用与网络套接字的使用大体上是类似的,但是也存在一些区别,主要有(1)和套接字绑定的地址结构体不同,本地套接字使用的结构体是 struct sockaddr_un ,而网络套接字使用的是 struct sockaddr_in;(2)协议族不同,本地套接字使用的是AF_UNIX 或AF_LOCAL, 网络套接字常用的是AF_INET;(3)对于使用本地套接字的C/S模型,服务器和客户端都需要显式绑定套接字描述符和地址信息,即(1)中提到的存放地址信息的结构体;(4)用本地套接字的C/S模型中,服务器和客户端都是通过 bind 函数创建本地套接字伪文件,服务器和客户端之间即是通过各自的套接字伪文件来产生连接然后进行数据通信。其余不同具体见代码。

1、服务器端代码

#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cctype>
#include <sys/un.h>
#include <stddef.h>

#include "wrap.h"

#define SERV_ADDR "serv.socket"

int main()
{
    int lfd, cfd, len, size, i;
    struct sockaddr_un servaddr, clieaddr;
    char buf[4096];

    lfd = Socket(AF_UNIX, SOCK_STREAM, 0); 

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sun_family = AF_UNIX;
    strcpy(servaddr.sun_path, SERV_ADDR);

    len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);

    unlink(SERV_ADDR);   // Make sure that the file("serv.socket") does not exist before bind,bacause
                         // bind will create it. 
    Bind(lfd, (struct sockaddr *)&servaddr, len);   // Note that the third parameter passed in is "len".

    Listen(lfd, 20);

    printf("Accept...\n");
    while(1) {
        len = sizeof(clieaddr);
        cfd = Accept(lfd, (struct sockaddr *)&clieaddr, (socklen_t *)&len);

        len -= offsetof(struct sockaddr_un, sun_path);   // Get the length of the file name of the client's local socket
        clieaddr.sun_path[len] = '\0';
        printf("client bind filename %s\n", clieaddr.sun_path);

        while((size = Read(cfd, buf, sizeof(buf))) > 0) {
            for(i = 0; i < size; i++)
                buf[i] = toupper(buf[i]);
            Write(cfd, buf, size);
        }
        close(cfd);

    }
    close(lfd);

    return 0;
}

2、客户端代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <cctype>
#include <cstddef>

#include "wrap.h"

#define SERV_ADDR "serv.socket"
#define CLIE_ADDR "clie.socket"

int main()
{
    int cfd, len;
    struct sockaddr_un servaddr, clieaddr;
    char buf[4096];

    cfd = Socket(AF_UNIX, SOCK_STREAM, 0); 

    memset(&clieaddr, 0, sizeof(clieaddr));
    clieaddr.sun_family = AF_UNIX;
    strcpy(clieaddr.sun_path, CLIE_ADDR);

    len = offsetof(struct sockaddr_un, sun_path) + strlen(clieaddr.sun_path);

    unlink(CLIE_ADDR);
    Bind(cfd, (struct sockaddr *)&clieaddr, len);

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sun_family = AF_UNIX;
    strcpy(servaddr.sun_path, SERV_ADDR);
    
    len = offsetof(struct sockaddr_un, sun_path)  + strlen(servaddr.sun_path);

    Connect(cfd, (struct sockaddr *)&servaddr, len);

    while(fgets(buf, sizeof(buf), stdin) != NULL) {
        Write(cfd, buf, strlen(buf));
        len = Read(cfd, buf, sizeof(buf));
        Write(STDOUT_FILENO, buf, len);
    }

    close(cfd);

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值