About AF_LOCAL in Linux
1. #include <stdio.h>
2. #include <sys/stat.h>
3. #include <sys/socket.h>
4. #include <sys/un.h>
5. #include <errno.h>
6. #include <stddef.h>
7. #include <string.h>
8.
9. // the max connection number of the server
10. #define MAX_CONNECTION_NUMBER 5
11.
12. /* * Create a server endpoint of a connection. * Returns fd if all OK, <0 on error. */
13. int unix_socket_listen(const char *servername)
14. {
15. int fd;
16. struct sockaddr_un un;
17. if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
18. {
19. return(-1);
20. }
21. int len, rval;
22. unlink(servername); /* in case it already exists */
23. memset(&un, 0, sizeof(un));
24. un.sun_family = AF_UNIX;
25. strcpy(un.sun_path, servername);
26. len = offsetof(struct sockaddr_un, sun_path) + strlen(servername);
27. /* bind the name to the descriptor */
28. if (bind(fd, (struct sockaddr *)&un, len) < 0)
29. {
30. rval = -2;
31. }
32. else
33. {
34. if (listen(fd, MAX_CONNECTION_NUMBER) < 0)
35. {
36. rval = -3;
37. }
38. else
39. {
40. return fd;
41. }
42. }
43. int err;
44. err = errno;
45. close(fd);
46. errno = err;
47. return rval;
48. }
49.
50. int unix_socket_accept(int listenfd, uid_t *uidptr)
51. {
52. int clifd, len, rval;
53. time_t staletime;
54. struct sockaddr_un un;
55. struct stat statbuf;
56. len = sizeof(un);
57. if ((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < 0)
58. {
59. return(-1);
60. }
61. /* obtain the client's uid from its calling address */
62. len -= offsetof(struct sockaddr_un, sun_path); /* len of pathname */
63. un.sun_path[len] = 0; /* null terminate */
64. if (stat(un.sun_path, &statbuf) < 0)
65. {
66. rval = -2;
67. }
68. else
69. {
70. if (S_ISSOCK(statbuf.st_mode) )
71. {
72. if (uidptr != NULL) *uidptr = statbuf.st_uid; /* return uid of caller */
73. unlink(un.sun_path); /* we're done with pathname now */
74. return clifd;
75. }
76. else
77. {
78. rval = -3; /* not a socket */
79. }
80. }
81. int err;
82. err = errno;
83. close(clifd);
84. errno = err;
85. return(rval);
86. }
87.
88. void unix_socket_close(int fd)
89. {
90. close(fd);
91. }
92.
93. int main(void)
94. {
95. int listenfd,connfd;
96. listenfd = unix_socket_listen("foo.sock");
97. if(listenfd<0)
98. {
99. printf("Error[%d] when listening...\n",errno);
100. return 0;
101. }
102. printf("Finished listening...\n",errno);
103. uid_t uid;
104. connfd = unix_socket_accept(listenfd, &uid);
105. unix_socket_close(listenfd);
106. if(connfd<0)
107. {
108. printf("Error[%d] when accepting...\n",errno);
109. return 0;
110. }
111. printf("Begin to recv/send...\n");
112. int i,n,size, rs;
113. char rvbuf[2048];
114. for(i=0;i<2;i++)
115. {
116. //===========接收==============
117. do
118. {
119. size = recv(connfd, rvbuf, 804, 0);
120. if(size>=0)
121. {
122. // rvbuf[size]='\0';
123. printf("Recieved Data[%d]:%c...%c\n",size,rvbuf[0],rvbuf[size-1]);
124. }
125. if(size==-1)
126. {
127. printf("Error[%d] when recieving Data:%s.\n",errno,strerror(errno));
128. break;
129. }
130.
131. if(size != sizeof(rvbuf))
132. rs = 1;// 需要再次讀取
133. else
134. rs = 0;
135. }while (rs);
136. /*
137. //===========傳送==============
138. memset(rvbuf, 'c', 2048);
139. size = send(connfd, rvbuf, 2048, 0);
140. if(size>=0)
141. {
142. printf("Data[%d] Sended.\n",size);
143. }
144. if(size==-1)
145. {
146. printf("Error[%d] when Sending Data.\n",errno);
147. break;
148. }
149. */
150. sleep(30);
151. }
152. unix_socket_close(connfd);
153. printf("Server exited.\n");
154. }