TheRiver | blog

You have reached the world's edge, none but devils play past here

0%

unix域套接字

参考

unp v1

概念

wikipedia的解释:

Unix domain socket 或者 IPC socket是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信。与管道相比,Unix domain sockets 既可以使用字节流,又可以使用数据队列,而管道通信则只能使用字节流。Unix domain sockets的接口和Internet socket很像,但它不使用网络底层协议来通信。Unix domain socket 的功能是POSIX操作系统里的一种组件。

Unix domain sockets 使用系统文件的地址来作为自己的身份。它可以被系统进程引用。所以两个进程可以同时打开一个Unix domain sockets来进行通信。不过这种通信方式是发生在系统内核里而不会在网络里传播。

demo

server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <sys/un.h>
#include <unistd.h>
#include <sys/socket.h>
#include <cstdlib>
#include <errno.h>

using namespace std;

int main(int argc, char **argv)
{
if (argc != 2)
return -1;

int listfd = 0;
int connfd = 0;
socklen_t clilen = 0;

struct sockaddr_un cliaddr = {0};
struct sockaddr_un seraddr = {0};

listfd = socket(AF_UNIX, SOCK_STREAM, 0);
unlink(argv[1]);

seraddr.sun_family = AF_UNIX;
strncpy(seraddr.sun_path, argv[1], sizeof(seraddr.sun_path) - 1);

bind(listfd, (sockaddr *)&seraddr, sizeof(seraddr));

listen(listfd, 5);

clilen = sizeof(cliaddr);
connfd = accept(listfd, (sockaddr *)&cliaddr, &clilen);
if (connfd < 0)
return -2;

char buf[256] = {0};
int n = 0;

while(1)
{
n = read(connfd, buf, 256);
cout << n << endl;
if (n > 0)
{
cout << buf << endl;
write(connfd, buf, n);
}
else if (n < 0 && errno == EINTR)
cout << "EINTR" << endl;
else if (n < 0)
cout << "read err!" << endl;
}

return 0;
}

client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <sys/un.h>
#include <unistd.h>
#include <sys/socket.h>
#include <cstdlib>
#include <errno.h>

using namespace std;

int main(int argc, char **argv)
{
if (argc != 2)
return -1;

int sockfd = 0;
struct sockaddr_un seraddr = {0};

sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

seraddr.sun_family = AF_UNIX;
strncpy(seraddr.sun_path, argv[1], sizeof(seraddr.sun_path) - 1);

int ret = connect(sockfd, (sockaddr *)&seraddr, sizeof(seraddr));
if (ret < 0)
return -2;

char buf[256] = {0};
int n = 0;

while(cin >> buf)
{
write(sockfd, buf, strlen(buf));
n = read(sockfd, buf, 256 - 1);
if (n > 0)
cout << "rsp: " << buf << endl;
if (n < 0 && errno == EINTR)
continue;
else if (n < 0)
{
cout << "read err!" << endl;
return -3;
}
}

return 0;
}

[root@riverwang1591252165612-0 ]# ./client /tmp/unixfd 
111
rsp: 111
sss
rsp: sss
aaaaaaaa
rsp: aaaaaaaa
zzzzzzzzzzzz
rsp: zzzzzzzzzzzz

ENDDING

070903.jpg

----------- ending -----------