域套接字简介及范例(一)————流形式

域套接字使用方式和TCP/IP一样:

相比共享内存而言,它是主动发数据,被动收数据,拥有阻塞和非阻塞模式以及它们之间的切换。

域套接字传输稳定,无论是否建立连接,都不会发生丢包的情况。同时,它的传输速度比本地环回快很多。

域套接字如同TCP/IP一样,也分为流(SOCK_STREAM)和数据包(SOCK_DGRAM),采用流传输时也需要解决粘包问题。

如果在文件系统中,已经有了一个文件和指定的路径名相同,则绑定会失败(返回错误EADDRINUSE)。所以,一个套接字只能绑定到一个路径上,同样的,一个路径也只能被一个套接字绑定。

服务器端:

#include "../common.h"
#define FILE_PATH "./my_socket"

int main()
{
    int serFd,cliFd;
    int ret = -1;
    struct sockaddr_un s_addr,c_addr;
    char buffer[1024] = {0};
    serFd = socket(AF_UNIX,SOCK_STREAM,0); //为SOCK_STREAM时仍需处理粘包问题
    if(serFd < 0)
    {
        perror("socket");
        return -1;
    }
    s_addr.sun_family = AF_UNIX;
    int  addr_len = sizeof(s_addr);
    strcpy(s_addr.sun_path,FILE_PATH);

    unlink(FILE_PATH);
    if( bind(serFd,(struct sockaddr*)&s_addr,sizeof(s_addr)) < 0)
    {
        perror("bind");
        return -1;
    }
    if(listen(serFd,5) < 0)
    {
        perror("listen");
        return -1;
    }

    fd_set ser_set, rser_set;
    FD_ZERO(&ser_set);
    FD_SET(serFd, &ser_set);
 
    int maxfd = serFd;
    struct timeval tv0;
    while(true)
    {
        rser_set = ser_set;
        printf("wait select ....\n");
        tv0.tv_sec = 5;
        tv0.tv_usec = 0;
        ret = select(maxfd + 1, &rser_set, NULL, NULL,NULL);  //对读进行操作等待(NULL无限等待)
 
        if (ret == 0)
        {
            printf("select ret == 0 ....\n");
            continue;
        }
        if (ret < 0)
        {
            perror("select");
            sleep(1);
            continue;
        }
        if (FD_ISSET(serFd, &rser_set))
        {
            if (cliFd > 0)
            {
                close(cliFd);
                cliFd = -1;
            }
            cliFd = accept(serFd, NULL, NULL);
            if (cliFd < 0)
            {
                perror("accept");
                continue;
            }
            printf("\nrecv client_fd data ...\n");

            if (cliFd > maxfd)
            {
                maxfd = cliFd;
            }
            FD_SET(cliFd, &ser_set);
        }
        else
        {
            if (cliFd < 0)
                continue;
            memset(buffer, 0, 4096);
            int iDataNum = recv(cliFd, buffer, 4096, MSG_DONTWAIT);
            if (iDataNum <= 0)
            {
                FD_CLR(cliFd, &ser_set);
 
                if (iDataNum < 0)
                {
                    perror("recv");
                }
                else
                {
                    if (cliFd > 0)
                    {
                        close(cliFd);
                    }
                    cliFd = -1;
                }
                continue;
            }
            else
            {
                printf("buffer form cli: '%s'  iDataNum:%d\n", buffer,iDataNum);
            }
        }
    }

    close(serFd);
    if(cliFd > 0)close(cliFd);
    return 0;
}

客户端:

#include "../common.h"
#define FILE_PATH "./my_socket"
int main()
{
    int fd;
    int ret = -1;
    struct sockaddr_un s_addr;
    fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if(fd < 0)
    {
        perror("socket");
        return -1;
    }
    s_addr.sun_family = AF_UNIX;
    strcpy(s_addr.sun_path,FILE_PATH);
    if(connect(fd,(struct sockaddr*)&s_addr,sizeof(s_addr)) < 0)
    {
        perror("connect");
    };
    char buf[1024] = "I'm client";
    while(true)
    {
        ret = write(fd,buf,strlen(buf)+1); //与TCP一样
        printf("write ret = %d\n",ret);
        if(ret < 0)break;
    }

    close(fd);
    
}

结果展示:

wait select ....
buffer form cli: I'm client  iDataNum:44
wait select ....
buffer form cli: I'm client  iDataNum:22
wait select ....
buffer form cli: I'm client  iDataNum:22
wait select ....
buffer form cli: I'm client  iDataNum:33
wait select ....
buffer form cli: I'm client  iDataNum:22
wait select ....
buffer form cli: I'm client  iDataNum:22
wait select ....
buffer form cli: I'm client  iDataNum:22
wait select ....
buffer form cli: I'm client  iDataNum:22
wait select ....
buffer form cli: I'm client  iDataNum:22
wait select ....
buffer form cli: I'm client  iDataNum:33
wait select ....
buffer form cli: I'm client  iDataNum:22
wait select ....
buffer form cli: I'm client  iDataNum:22
wait select ....

可以看到有粘包存在(因为是字符串,所以打印结果是正确的)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值