概述
这里做个备份,毕竟在对第三方网络库或者自己开发网络库做压测时,需要有比较基准,这个基准必须是最简陋的乞丐版,即只调用系统API实现的最简单的TCP客户端和服务器。例子给出的是最简单的Ping-Pong测试,很形象了,像打乒乓球一样将数据丢来丢去。
一.服务端
//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;
}
二.客户端
// 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++之最简单的TCP客户端和服务器(Windows版)一.服务端二.客户端所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复