UNIX域数据报套接字的流程可参考UDP套接字编程。其服务器端流程及代码示例如下所示。
(1)创建UNIX域数据报套接字。
(2)填充服务器本地信息结构体。
(3)将套接字与服务器本地信息结构体绑定。
(4)进行通信 (recvfrom/sendto)。
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, clientaddr;
21 socklen_t addrlen = sizeof(serveraddr);
22 char buf[N] = {};
23
24 //第一步:创建套接字
25 if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 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(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0){
35 errlog("fail to bind");
36 }
37
38 ssize_t bytes;
39 while(1){
40 if((bytes = recvfrom(sockfd, buf, N, 0,\
41 (struct sockaddr *)&clientaddr, &addrlen)) < 0){
42 errlog("fail to recvfrom");
43 }
44 else{
45 printf("clientaddr.sun_path = %s\n", clientaddr.sun_path);
46
47 if(strncmp(buf, "quit", 4) == 0){
48 printf("client quit\n");
49 break;
50 }
51 else{
52 printf("client: %s\n", buf);
53
54 strcat(buf, " *_*");
55
56 if(sendto(sockfd, buf, N, 0,\
57 (struct sockaddr *)&clientaddr, addrlen) < 0){
58 errlog("fail to sendto");
59 }
60 }
61 }
62 }
63
64 close(sockfd);
65
66 return 0;
67 }
客户端的流程与代码示例如下所示。
(1)创建UNIX域数据报套接字。
(2)填充服务器本地信息结构体。
(3)填充客户端本地信息结构体。
(4)将套接字与客户端本地信息结构体绑定。
(5)进行通信 (sendto/recvfrom)。
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_DGRAM, 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 struct sockaddr_un clientaddr;
35 clientaddr.sun_family = AF_UNIX;
36 strcpy(clientaddr.sun_path, argv[2]);
37
38 if(bind(sockfd, (struct sockaddr *)&clientaddr, addrlen) < 0){
39 errlog("fail to bind");
40 }
41
42 while(1){
43 fgets(buf, N, stdin);
44 buf[strlen(buf) - 1] = '\0';
45
46 if(sendto(sockfd, buf, N, 0,\
47 (struct sockaddr *)&serveraddr, addrlen) < 0){
48 errlog("fail to sendto");
49 }
50
51 if(strncmp(buf, "quit", 4) == 0){
52 printf("client is quited\n");
53 break;
54 }
55 else{
56 if(recvfrom(sockfd, buf, N, 0,\
57 (struct sockaddr *)&serveraddr, &addrlen) < 0){
58 errlog("fail to recv");
59 }
60 printf("server: %s\n", buf);
61 }
62 }
63 close(sockfd);
64
65 return 0;
66 }