我是靠谱客的博主 善良服饰,这篇文章主要介绍C++之最简单的TCP客户端和服务器(Windows版)一.服务端二.客户端,现在分享给大家,希望可以做个参考。

这里做个备份,毕竟在对第三方网络库或者自己开发网络库做压测时,需要有比较基准,这个基准必须是最简陋的乞丐版,即只调用系统API实现的最简单的TCP客户端和服务器。例子给出的是最简单的Ping-Pong测试,很形象了,像打乒乓球一样将数据丢来丢去。

一.服务端

复制代码
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
//server.cpp #include<iostream> #include<winsock.h> //windows平台的网络库头文件 #pragma comment(lib,"ws2_32.lib") //库文件 #define PORT 5050 #define BUFSIZ 512 int main() { //初始化套接字库 //WSA windows socket async windows异步套接字 //WSAStartup启动套接字 参数形式:WORD WSADATA //parm1:请求的socket版本 2.2 2.1 1.0 //parm2:传出参数 WORD w_req = MAKEWORD(2, 2);//版本号 WSADATA wsadata; //成功:WSAStartup函数返回零 if (WSAStartup(w_req, &wsadata) != 0) { std::cout << "WSAStartup failed" << std::endl; return -1; } else { std::cout << "WSAStartup succeed" << std::endl; } //1.创建空的Socket //parm1:af 地址协议族 ipv4 ipv6 //parm2:type 传输协议类型 流式套接字(SOCK_STREAM) 数据报 //parm3protocl 使用具体的某个传输协议 SOCKET s_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s_server == INVALID_SOCKET) { std::cout << "Create socket failed" << std::endl; WSACleanup(); return -1; } else { std::cout << "Create socket succeed" << std::endl; } //2.给socket绑定ip地址和端口号 struct sockaddr_in server_addr; //sockaddr_in, sockaddr 老版本和新版的区别 server_addr.sin_family = AF_INET; //和创建socket时必须一样 server_addr.sin_port = htons(PORT); //端口号 大端(高位)存储(本地)和小端(低位)存储(网络),两个存储顺序是反着的 htons 将本地字节序转为网络字节序 server_addr.sin_addr.s_addr = INADDR_ANY; //3.绑定 if (bind(s_server, (PSOCKADDR)&server_addr, sizeof(sockaddr_in)) == SOCKET_ERROR) { std::cout << "Bind failed" << std::endl; WSACleanup(); return -1; } else { std::cout << "Bind succeed" << std::endl; } //4.设置套接字为监听状态 SOMAXCONN 监听的端口数 if (listen(s_server, SOMAXCONN) < 0) { std::cout << "Listen failed" << std::endl; WSACleanup(); return -1; } else { std::cout << "Listen succeed" << std::endl; } SOCKET s_client; std::cout << "Wait client connect..." << std::endl; struct sockaddr_in client_addr; int addr_len = sizeof (sockaddr_in); s_client = accept(s_server, (SOCKADDR*)&client_addr, &addr_len); if (s_client == INVALID_SOCKET) { std::cout << "Accept failed" << std::endl; WSACleanup(); return -1; } char buf[BUFSIZ]; ZeroMemory(buf, BUFSIZ); while (true) { int ret = recv(s_client, buf, BUFSIZ, 0); if (ret > 0){ std::cout << "Recv from client: " << buf << std::endl; } else if (ret == 0) { std::cout << "s_client closed" << std::endl; closesocket(s_server); WSACleanup(); return -1; } else { std::cout << "Recv failed: " << GetLastError() << std::endl; closesocket(s_server); closesocket(s_client); WSACleanup(); return -1; } ret = send(s_client, buf, BUFSIZ, 0); if (SOCKET_ERROR != ret) { std::cout << "Send to client: " << buf << std::endl; } else { std::cout << "Send failed: " << GetLastError() << std::endl; closesocket(s_server); closesocket(s_client); WSACleanup(); return -1; } } //关闭套接字 closesocket(s_server); closesocket(s_client); //释放DLL资源 WSACleanup(); return 0; }

二.客户端

复制代码
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
// client.cpp #include<iostream> #include<winsock.h> //windows平台的网络库头文件 #pragma comment(lib,"ws2_32.lib") //库文件 #define PORT 5050 #define BUFSIZ 512 int main() { //初始化套接字库 //WSA windows socket async windows异步套接字 //WSAStartup启动套接字 参数形式:WORD WSADATA //parm1:请求的socket版本 2.2 2.1 1.0 //parm2:传出参数 WORD w_req = MAKEWORD(2, 2);//版本号 WSADATA wsadata; //成功:WSAStartup函数返回零 if (WSAStartup(w_req, &wsadata) != 0) { std::cout << "WSAStartup failed" << std::endl; return -1; } else { std::cout << "WSAStartup succeed" << std::endl; } //1.创建空的Socket //parm1:af 地址协议族 ipv4 ipv6 //parm2:type 传输协议类型 流式套接字(SOCK_STREAM) 数据报 //parm3protocl 使用具体的某个传输协议 SOCKET c_client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (c_client == INVALID_SOCKET) { std::cout << "Create socket failed" << std::endl; WSACleanup(); return -1; } else { std::cout << "Create socket succeed" << std::endl; } //2.给socket绑定ip地址和端口号 struct sockaddr_in client_addr; // sockaddr_in, sockaddr 老版本和新版的区别 client_addr.sin_family = AF_INET; // 和创建socket时必须一样 client_addr.sin_port = htons(PORT); // 端口号 大端(高位)存储(本地)和小端(低位)存储(网络),两个存储顺序是反着的 htons 将本地字节序转为网络字节序 client_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //inet_addr将点分十进制的ip地址转为二进制 //3.连接服务端 if (connect(c_client, (PSOCKADDR)&client_addr, sizeof(sockaddr_in))== INVALID_SOCKET) { std::cout << "Connect failed" << std::endl; closesocket(c_client); WSACleanup(); return -1; } else { std::cout << "Connect succeed" << std::endl; } char buf[BUFSIZ] ="Hello World"; //发送,接收数据 while (true) { int ret = send(c_client, buf, BUFSIZ, 0); if (SOCKET_ERROR != ret) { std::cout << "Send to server: " << buf << std::endl; } else { std::cout << "Send failed: " << GetLastError() << std::endl; closesocket(c_client); WSACleanup(); return -1; } ret = recv(c_client, buf, BUFSIZ, 0); if (ret > 0){ std::cout << "Recv from server: " << buf << std::endl; } else if (ret == 0) { std::cout << "c_client closed" << std::endl; closesocket(c_client); WSACleanup(); return -1; } else { std::cout << "Recv failed: " << GetLastError() << std::endl; closesocket(c_client); WSACleanup(); return -1; } } //关闭套接字 closesocket(c_client); //释放DLL资源 WSACleanup(); return 0; }

原文链接:https://blog.csdn.net/caoshangpa/article/details/78611048

最后

以上就是善良服饰最近收集整理的关于C++之最简单的TCP客户端和服务器(Windows版)一.服务端二.客户端的全部内容,更多相关C++之最简单内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部