Unix域套接字的初级应用

本文介绍了一个基于Unix字节流套接字和数据报套接字实现的回显服务示例。服务端接收客户端发送的消息并将其返回。代码包括服务端与客户端的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unix字节流套接字的回显服务:

服务端代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>

#define UNIX_PATH "/home/marco/sock.str"
#define BUFSIZE 4096
#define LISTENQ 100
void sig_child(int signo) {
    int ppid;
    while ((ppid = waitpid(-1,NULL,WNOHANG)) > 0) {
        printf("child process: %d terminated\n",ppid);
    }
}
void server_echo(int fd) {
    char send[BUFSIZE];
    int n;
    while ((n = read(fd,send,BUFSIZE)) > 0) {
        if (write(fd,send,n) != n) {
            printf("write error: %s\n",strerror(errno));
            exit(1);
        }
    }
}
int main(int argc,char** argv) {
    int sockfd;
    if ((sockfd = socket(AF_LOCAL,SOCK_STREAM,0)) < 0) {
        printf("socket error: %s\n",strerror(errno));
        exit(1);
    }
    unlink(UNIX_PATH);
    struct sockaddr_un serveraddr;
    bzero(&serveraddr,sizeof(struct sockaddr_un));
    serveraddr.sun_family = AF_LOCAL;
    strcpy(serveraddr.sun_path,UNIX_PATH);
    if (bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(struct sockaddr_un)) < 0) {
        printf("bind error: %s\n",strerror(errno));
        exit(1);
    }

    if (listen(sockfd,LISTENQ) < 0) {
        printf("lsiten error: %s\n",strerror(errno));
        exit(1);
    }

    int connfd;
    int pid;
    if (signal(SIGCHLD,sig_child) == SIG_ERR) {
        printf("signal error: %s\n",strerror(errno));
        exit(1);
    }
    for (; ;) {
        if ((connfd = accept(sockfd,NULL,NULL)) < 0) {
            if (errno == EINTR) {
                continue;
            }else {
                printf("accept error: %s\n",strerror(errno));
                exit(1);
            }
        }
        if ((pid = fork()) < 0) {
            printf("fork error: %s\n",strerror(errno));
            exit(1);
        }else if (pid == 0) {
            close(sockfd);
            server_echo(connfd);
            close(connfd);
            exit(0);
        }
        close(connfd);  
    }   
}

客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/un.h>

#define UNIX_PATH "/home/marco/sock.str"
#define BUFSIZE 4096

void client_echo(int fd) {
    char recv[BUFSIZE];
    int n;
    while ((n = read(STDIN_FILENO,recv,BUFSIZE)) > 0) {
        if (write(fd,recv,n) != n) {
            printf("write error: %s\n",strerror(errno));
            exit(1);
        }
        if ((n = read(fd,recv,BUFSIZE)) < 0) {
            printf("read error: %s\n",strerror(errno));
            exit(1);
        }

        if (write(STDOUT_FILENO,recv,n) != n) {
            printf("write error: %s\n",strerror(errno));
            exit(1);
        }
    }
}
int main(int argc,char** argv) {
    int sockfd;
    if ((sockfd = socket(AF_LOCAL,SOCK_STREAM,0)) < 0) {
        printf("socket error: %s\n",strerror(errno));
        exit(1);
    }

    struct sockaddr_un serveraddr;
    bzero(&serveraddr,sizeof(struct sockaddr_un));
    serveraddr.sun_family = AF_LOCAL;
    strcpy(serveraddr.sun_path,UNIX_PATH);
    if (connect(sockfd,(struct sockaddr*)&serveraddr,sizeof(struct sockaddr_un)) < 0) {
        printf("connect error: %s\n",strerror(errno));
        exit(1);
    }
    client_echo(sockfd);
    return 0;
}

Unix域数据报套接字回显服务:

服务器端代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/un.h>

#define BUFSIZE 4096
#define UNIX_PATH "/home/marco/tmp.sock"

int main(int argc,char** argv) {
    int sockfd;
    if ((sockfd = socket(AF_LOCAL,SOCK_DGRAM,0)) < 0) {
        printf("socket error: %s\n",strerror(errno));
        exit(1);
    }

    unlink(UNIX_PATH);
    struct sockaddr_un serveraddr;
    bzero(&serveraddr,sizeof(struct sockaddr_un));
    serveraddr.sun_family = AF_LOCAL;
    strcpy(serveraddr.sun_path,UNIX_PATH);
    if (bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(struct sockaddr_un)) < 0) {
        printf("bind error: %s\n",strerror(errno));
        exit(1);
    }
    struct sockaddr_un clientaddr;
    socklen_t len = sizeof(struct sockaddr_un);
    char recv[BUFSIZE];
    int n;
    for (; ;) {
        if ((n = recvfrom(sockfd,recv,BUFSIZE,0,(struct sockaddr*)&clientaddr,&len)) < 0) {
            printf("receive from client fail: %s\n",strerror(errno));
            exit(1);
        }
        if (sendto(sockfd,recv,n,0,(struct sockaddr*)&clientaddr,len) != n) {
            printf("send message to client error: %s\n",strerror(errno));
            exit(1);
        }
    }
}

客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#define UNIX_PATH "/home/marco/tmp.sock"
#define BUFSIZE 4096
#define TMP_CLIENT "/home/marco/client.sock"

void client_echo(int fd,struct sockaddr* to,socklen_t tolen) {
    char send[BUFSIZE];
    int n;
    struct sockaddr_un from;
    socklen_t len = sizeof(struct sockaddr_un);
    while ((n = read(STDIN_FILENO,send,BUFSIZE)) > 0) {
        if (sendto(fd,send,n,0,to,tolen) != n) {
            printf("send message to server error: %s\n",strerror(errno));
            exit(1);
        }

        if ((n = recvfrom(fd,send,BUFSIZE,0,(struct sockaddr*)&from,&len)) < 0) {
            printf("receive from server fail: %s\n",strerror(errno));
            exit(1);
        }
        if (write(STDOUT_FILENO,send,n) != n) {
            printf("write error: %s\n",strerror(errno));
            exit(1);
        }
    }
}

int main() {
    int sockfd;
    if ((sockfd = socket(AF_LOCAL,SOCK_DGRAM,0)) < 0) {
        printf("socket error: %s\n",strerror(errno));
        exit(1);
    }

    struct sockaddr_un serveraddr;
    bzero(&serveraddr,sizeof(struct sockaddr_un));
    serveraddr.sun_family = AF_LOCAL;
    strcpy(serveraddr.sun_path,UNIX_PATH);

    struct sockaddr_un clientaddr;
    bzero(&clientaddr,sizeof(struct sockaddr_un));
    clientaddr.sun_family = AF_LOCAL;
    unlink(TMP_CLIENT);
    strcpy(clientaddr.sun_path,TMP_CLIENT);
    if (bind(sockfd,(struct sockaddr*)&clientaddr,sizeof(struct sockaddr_un)) < 0) {
        printf("bind error: %s\n",strerror(errno));
        exit(1);
    }
    client_echo(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值