UNIX域流式套接字简单示例(无差错,可编译)

UNIX域流式套接字的用法与TCP套接字基本一致,区别就在于使用的协议和地址不同。
UNIX域流式套接字服务器器端流程以及示例代码如下。
(1)创建UNIX域流式套接字。
(2)将套接字文件描述符与本地信息结构体绑定。
(3)设置监听模式。
(4)接收客户端的连接请求。
(5)发送、接收数据。

  1 #include <stdio.h>
  2 #include <arpa/inet.h>
  3 #include <sys/types.h>
  4 #include <sys/socket.h>
  5 #include <stdlib.h>
  6 #include <unistd.h>
  7 #include <string.h>
  8 #include <strings.h>
  9 #include <sys/un.h>
 10 
 11 #define N 128
 12 #define errlog(errmsg) do{perror(errmsg);\
 13                           printf("%s--%s--%d\n",\ 
 14                                   __FILE__, __func__, __LINE__);\
 15                           exit(1);\
 16                          }while(0)
 17 
 18 int main(int argc, const char *argv[])
 19 {
 20     int sockfd, acceptfd;
 21     struct sockaddr_un serveraddr, clientaddr;
 22     socklen_t addrlen = sizeof(serveraddr);
 23     char buf[N] = {};                                                                                                                                                                                                  
 24 
 25     //初始化结构体
 26     bzero(&serveraddr, addrlen);
 27     bzero(&clientaddr, addrlen);
 28 
 29     //第一步:创建套接字
 30     if((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
 31         errlog("fail to socket");
 32     }
 33 
 34     //第二步:填充服务器本地信息结构体
 35     serveraddr.sun_family = AF_UNIX;
 36     strcpy(serveraddr.sun_path, argv[1]);
 37 	
 38     //第三步:将套接字与服务器网络信息结构体绑定
 39     if(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0){
 40         errlog("fail to bind");
 41     }
 42 
 43     //第四步:将套接字设置为被动监听模式
 44     if(listen(sockfd, 5) < 0){
 45         errlog("fail to listen");
 46     }
 47 
 48     //第五步:阻塞等待客户端的连接请求
 49     if((acceptfd = accept(sockfd,\
 50                     (struct sockaddr *)&clientaddr, &addrlen)) < 0){
 51         errlog("fail to accept");
 52     }
 53 
 54     ssize_t bytes;
 55     while(1){
 56         if((bytes = recv(acceptfd, buf, N, 0)) < 0){
 57             errlog("fail to recv");
 58         }
 59         else if(bytes == 0){
 60             printf("NO DATA\n");
 61             exit(1);
 62         }
 63         else{
 64             if(strncmp(buf, "quit", 4) == 0){
 65                 printf("client quit\n");
 66                 break;
 67             }
 68             else{
 69                 printf("client: %s\n", buf);
 70 
 71                 strcat(buf, " *_*");
 72 
 73                 if(send(acceptfd, buf, N, 0) < 0){
 74                     errlog("fail to send");
 75                 }
 76             }
 77         }
 78     }
 79 
 80     close(acceptfd);
 81     close(sockfd);
 82 
 83     return 0;
 84 }

UNIX域流式套接字客户端流程及代码示例如下。
(1)创建UNIX域流式套接字。
(2)指定服务器端地址(套接字文字)。
(3)建立连接。
(4)发送、接收数据。

  1 #include <stdio.h>
  2 #include <arpa/inet.h>
  3 #include <sys/types.h>
  4 #include <sys/socket.h>
  5 #include <stdlib.h>
  6 #include <unistd.h>
  7 #include <string.h>
  8 #include <sys/un.h>
  9 
 10 #define N 128
 11 #define errlog(errmsg) do{perror(errmsg);\
 12                           printf("%s--%s--%d\n",\ 
 13                                   __FILE__, __func__, __LINE__);\
 14                           exit(1);\
 15                          }while(0)
 16 
 17 int main(int argc, const char *argv[])
 18 {
 19     int sockfd;
 20     struct sockaddr_un serveraddr;
 21     socklen_t addrlen = sizeof(serveraddr);
 22     char buf[N] = {};
 23 
 24     //第一步:创建套接字
 25     if((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
 26         errlog("fail to socket");
 27     }                                                                                                                                                                                                                  
 28 
 29     //第二步:填充服务器本地信息结构体
 30     serveraddr.sun_family = AF_UNIX;
 31     strcpy(serveraddr.sun_path, argv[1]);
 32 
 33     //第三步:发送客户端连接请求
 34     if(connect(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0){
 35         errlog("fail to connect");
 36     }
 37 
 38     while(1){
 39         fgets(buf, N, stdin);
 40         buf[strlen(buf) - 1] = '\0';
 41 
 42         if(send(sockfd, buf, N, 0) < 0){
 43             errlog("fail to send");
 44         }
 45 
 46         if(strncmp(buf, "quit", 4) == 0){
 47             printf("client is quited\n");
 48             break;
 49         }
 50         else {
 51             if(recv(sockfd, buf, N, 0) < 0){
 52                 errlog("fail to recv");
 53             }
 54 
 55             printf("server: %s\n", buf);
 56         }
 57     }
 58 
 59     close(sockfd);
 60 
 61     return 0;
 62 }   

上述客户端代码中,需要注意的是,UNIX域数据报套接字与网络数据报套接字(UDP)不同的是前者的客户端一定要绑定自己的信息结构体。数据报套接字在用于网络通信时,服务器可以为客户端自动分配地址和端口号。而在本地通信时,服务器不会为客户端分配套接字文件(本地信息结构体)。如果客户端不绑定自己的信息结构体,服务器则无法知道客户端是谁。
先运行服务器端,再运行客户端,在客户端终端输入发送的数据即可。客户端的运行结果如下所示,命令行传参为套接字文件的名称。客户端发送数据,服务器将数据修改之后,回复给客户端。输入“quit”,客户端与服务器退出。

linux@Master:~/1000phone/net/unix_dgram$ ./client dgram dgram_client
hello world
server: hello world *_*
quit
client is quited

服务器的运行结果如下所示。

linux@Master:~/1000phone/net/unix_dgram$ ./server dgram
clientaddr.sun_path = dgram_client
client: hello world
clientaddr.sun_path = dgram_client
client quit

在当前目录下自动创建的套接字文件如下所示。

linux@Master:~/1000phone/net/unix_dgram$ ls -l dgram*
srwxrwxr-x 1 linux linux 0  6月 21 15:16 dgram
srwxrwxr-x 1 linux linux 0  6月 21 15:16 dgram_client

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值