一、概述
使用本地socket通讯可以实现进程之间的通讯。
相关函数描述如下:
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
|
int socket( int domain, int type, int protocol); 函数说明: 创建本地域socket 函数参数: domain: AF_UNIX or AF_LOCAL type: SOCK_STREAM或者SOCK_DGRAM protocol: 0 表示使用默认协议 函数返回值: 成功: 返回文件描述符. 失败: 返回-1, 并设置 errno 值. 创建socket成功以后, 会在内核创建缓冲区, 下图是客户端和服务端内核缓冲区示意图. int bind( int sockfd, const struct sockaddr *addr, socklen_t addrlen); 函数说明: 绑定套接字 函数参数: socket: 由socket函数返回的文件描述符 addr: 本地地址 addlen: 本地地址长度 函数返回值: 成功: 返回文件描述符. 失败: 返回-1, 并设置 errno 值. 需要注意的是: bind函数会自动创建socket文件, 若在调用bind函数之前socket文件已经存在, 则调用bind会报错, 可以使用unlink函数在bind之前先删除文件. struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX or AF_LOCAL*/ char sun_path[108]; /* pathname */ }; |
整体使用步骤和网络通讯的socket是差不多的,如下所示:
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
|
tcp的本地套接字服务器流程: 创建套接字 socket(AF_UNIX,SOCK_STREAM,0) 绑定 struct sockaddr_un &强转 侦听 listen 获得新连接 accept 循环通信 read-write 关闭文件描述符 close tcp本地套接字客户端流程: 调用socket创建套接字 调用bind函数将socket文件描述和socket文件进行绑定. 不是必须的, 若无显示绑定会进行隐式绑定,但服务器不知道谁连接了. 调用connect函数连接服务端 循环通信read-write 关闭文件描述符 close |
二、代码示例
1.服务端代码示例
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
//本地socket通讯服务端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/un.h> int main(){ //创建socket int lfd = socket(AF_UNIX,SOCK_STREAM,0); if (lfd<0){ perror ( "socket error" ); return -1; } //删除socket文件,避免bind失败 unlink( "./server.sock" ); //绑定 struct sockaddr_un serv; bzero(&serv, sizeof (serv)); serv.sun_family = AF_UNIX; strcpy (serv.sun_path, "./server.sock" ); int ret = bind(lfd,( struct sockaddr *)&serv, sizeof (serv)); if (ret<0){ perror ( "bind error" ); return -1; } //监听 listen(lfd,10); //接收新的链接-accept struct sockaddr_un client; bzero(&client, sizeof (client)); socklen_t len = sizeof (client); int cfd = accept(lfd,( struct sockaddr*)&client,&len); if (cfd<0){ perror ( "accept error" ); return -1; } printf ( "cient->[%s]\n" ,client.sun_path); int n; char buf[1024]; while (1){ //读取数据 memset (buf,0x00, sizeof (buf)); n = read(cfd,buf, sizeof (buf)); if (n<=0){ printf ( "read error or client close ,n=[%d]\n" ,n); break ; } printf ( "n=[%d],buf=[%s]\n" ,n,buf); //发送数据 write(cfd,buf,n); } //关闭套接字 close(lfd); return 0; } |
2.客户端代码示例
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
//本地socket通信客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/un.h> int main(){ //创建socket int cfd = socket(AF_UNIX,SOCK_STREAM,0); if (cfd<0){ perror ( "socket error" ); return -1; } //删除socket文件,避免bind失败 unlink( "./client.sock" ); //绑定 struct sockaddr_un client; bzero(&client, sizeof (client)); client.sun_family= AF_UNIX; strcpy (client.sun_path, "./client.sock" ); int ret = bind(cfd,( struct sockaddr*)&client, sizeof (client)); if (ret<0){ perror ( "bind error" ); return -1; } struct sockaddr_un serv; bzero(&serv, sizeof (serv)); serv.sun_family = AF_UNIX; strcpy (serv.sun_path, "./server.sock" ); ret = connect(cfd,( struct sockaddr*)&serv, sizeof (serv)); if (ret<0){ perror ( "connect error" ); return -1; } int n; char buf[1024]; while (1){ memset (buf,0x00, sizeof (buf)); n = read(STDIN_FILENO,buf, sizeof (buf)); //发送数据 write(cfd,buf,n); //读取数据 memset (buf,0x00, sizeof (buf)); n = read(cfd,buf, sizeof (buf)); if (n<=0){ printf ( "read error or client close ,n=[%d]" ,n); break ; } printf ( "n=[%d],buf=[%s]" ,n,buf); } close(cfd); return 0; } |
到此这篇关于 使用C语言实现本地socket通讯的文章就介绍到这了,更多相关C语言本地socket通讯内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://www.cnblogs.com/tony-yang-flutter/p/15709973.html