TCP协议:
服务器 Server 客户端 Client
1. 确定协议版本 1. 确定协议版本
2. 创建socket 2. 创建socket
3. 确定协议地址簇 3. 获取服务器地址
4. 绑定
5. 监听
6. 接受客户端连接 4. 连接服务器
7. 通信 5. 通信
8. 关闭socket 6. 关闭socket
9. 清理协议版本信息 7. 清理协议版本信息
用vs2019写的
单个服务器,单个客户端
Server.cpp
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#include<WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#include<Windows.h>
#include<stdio.h>
#include<string>
int main()
{
// 1. 确定协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
printf("请求的版本不是2.2版本!\n");
WSACleanup();
return -1;
}
printf("请求的版本为2.2版本!\n");
// 2 创建socket
SOCKET sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //结构体
if (SOCKET_ERROR == sSocket)
{
printf("创建socke失败 :%d\n",GetLastError());
return -2;
}
printf("创建socke成功!\n");
// 3 确定服务器的协议地址簇
std::string ip = "127.0.0.1";
int port = 8080;
SOCKADDR_IN addr = {0};
addr.sin_family = AF_INET; // 和socket函数第一个参数保持一致
addr.sin_addr.S_un.S_addr = inet_addr(ip.c_str()); //
addr.sin_port = htons(port); //
// 4 绑定
int r = bind(sSocket,(sockaddr*)&addr, sizeof(addr));
if (-1 == r)
{
printf("绑定失败:%d\n",GetLastError());
// 8 断开连接
closesocket(sSocket);
// 9 清理协议版本信息
WSACleanup();
return -2;
}
printf("绑定成功!\n");
// 5. 监听
r = listen(sSocket,10);
if (-1 == r)
{
printf("监听失败:%d\n",GetLastError());
// 8 断开连接
closesocket(sSocket);
// 9 清理协议版本信息
WSACleanup();
return -2;
}
printf("监听成功!\n");
// 6 等待客户端连接
SOCKET cSocket = accept(sSocket,NULL,NULL);
if (SOCKET_ERROR == cSocket)
{
printf("服务器崩溃:%d\n",GetLastError());
// 8 断开连接
closesocket(sSocket);
// 9 清理协议版本信息
WSACleanup();
return -2;
}
printf("有客户端连接上服务器了!\n");
// 7 通信
char buff[256] = {0};
while (1)
{
r = recv(cSocket,buff,255,NULL); // 从客户端接收数据
if (r>0)
{
buff[r] = 0; // 添加结束符号
printf(">>%s\n",buff); // 输出
}
}
while (1);
return 0;
}
Client.cpp
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#include<Windows.h>
#include<stdio.h>
#include<iostream>
int main()
{
// 1. 确定协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
printf("请求的版本不是2.2版本!\n");
WSACleanup();
return -1;
}
printf("请求的版本为2.2版本!\n");
// 2 创建socket
SOCKET sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (SOCKET_ERROR == sSocket)
{
printf("创建socke失败 :%d\n", GetLastError());
return -2;
}
printf("创建socke成功!\n");
// 3 确定服务器的协议地址簇
std::string ip = "127.0.0.1";
int port = 8080;
SOCKADDR_IN addr = { 0 };
addr.sin_family = AF_INET; // 和socket函数第一个参数保持一致
addr.sin_addr.S_un.S_addr = inet_addr(ip.c_str()); // 服务器IP地址
addr.sin_port = htons(port); //
// 4 连接
int r = connect(sSocket, (sockaddr*)&addr, sizeof(addr));
if (-1 == r)
{
printf("连接失败:%d\n", GetLastError());
return -2;
}
printf("连接成功!\n");
// 5. 通信
char buff[256];
while (1)
{
memset(buff, 0, 256); // 清空数组
printf("发送服务器信息:");
scanf_s("%s", buff,sizeof(buff));
send(sSocket, buff, strlen(buff), NULL);
}
while (1);
return 0;
}
多个客户端连接同一个服务器
Server.cpp
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#include<WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#include<Windows.h>
#include<stdio.h>
#include<string>
#define NUM 1024 // 最大连接客户端
SOCKET cSocket[NUM];
int count;
// 和客户端通信的函数
void tongxin(int idx);
int main()
{
count = 0;
// 1. 确定协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
printf("请求的版本不是2.2版本!\n");
WSACleanup();
return -1;
}
printf("请求的版本为2.2版本!\n");
// 2 创建socket
SOCKET sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //结构体
if (SOCKET_ERROR == sSocket)
{
printf("创建socke失败 :%d\n",GetLastError());
return -2;
}
printf("创建socke成功!\n");
// 3 确定服务器的协议地址簇
std::string ip = "127.0.0.1";
int port = 8080;
SOCKADDR_IN addr = {0};
addr.sin_family = AF_INET; // 和socket函数第一个参数保持一致
addr.sin_addr.S_un.S_addr = inet_addr(ip.c_str()); // 本机IP地址
//addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //
addr.sin_port = htons(port); // 大小端转换 在10000左右
//printf("addr = %d \n",sizeof(addr));
// 4 绑定
int r = bind(sSocket,(sockaddr*)&addr, sizeof(addr));
if (-1 == r)
{
printf("绑定失败:%d\n",GetLastError());
// 8 断开连接
closesocket(sSocket);
// 9 清理协议版本信息
WSACleanup();
return -2;
}
printf("绑定成功!\n");
// 5. 监听
r = listen(sSocket,10);
if (-1 == r)
{
printf("监听失败:%d\n",GetLastError());
// 8 断开连接
closesocket(sSocket);
// 9 清理协议版本信息
WSACleanup();
return -2;
}
printf("监听成功!\n");
// 6 等待客户端连接
for(int i =0 ;i < NUM; i++)
{
cSocket[i] = accept(sSocket, NULL, NULL);
if (SOCKET_ERROR == cSocket[i])
{
printf("服务器崩溃:%d\n", GetLastError());
// 8 断开连接
closesocket(sSocket);
// 9 清理协议版本信息
WSACleanup();
return -3;
}
printf("有客户端连接上服务器了: %d \n",i);
count++;
// 创建线程和客户端通信
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)tongxin, (LPVOID)i, NULL, NULL);
}
while (1);
return 0;
}
// 和客户端通信
void tongxin(int idx)
{
// 7 通信
char buff[256] = { 0 };
int r;
char temp[256];
while (1)
{
r = recv(cSocket[idx], buff, 255, NULL); // 从客户端接收数据
if (r > 0)
{
buff[r] = 0; // 添加结束符号
printf(">>%d:%s\n",idx, buff); // 输出
// 发送给当前连上服务器的所有客户端
memset(temp,0,256);
sprintf(temp, "%d:%s",idx,buff);
for (int i = 0; i < count; i++)
{
send(cSocket[i],temp,strlen(temp),NULL);
}
}
}
}
Client.cpp
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#include<Windows.h>
#include<stdio.h>
#include<iostream>
#include<graphics.h> // easyX
SOCKET sSocket;
void scanfAndSend();
int main()
{
initgraph(200,400,1); // 俩个窗口
// 1. 确定协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
printf("请求的版本不是2.2版本!\n");
WSACleanup();
return -1;
}
printf("请求的版本为2.2版本!\n");
// 2 创建socket
sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (SOCKET_ERROR == sSocket)
{
printf("创建socke失败 :%d\n", GetLastError());
return -2;
}
printf("创建socke成功!\n");
// 3 确定服务器的协议地址簇
std::string ip = "127.0.0.1";
int port = 8080;
SOCKADDR_IN addr = { 0 };
addr.sin_family = AF_INET; // 和socket函数第一个参数保持一致
addr.sin_addr.S_un.S_addr = inet_addr(ip.c_str()); // 服务器IP地址
//addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // 本机IP地址
addr.sin_port = htons(port); // 大小端转换 在10000左右
// 4 连接
int r = connect(sSocket, (sockaddr*)&addr, sizeof(addr));
if (-1 == r)
{
printf("连接失败:%d\n", GetLastError());
return -2;
}
printf("连接成功!\n");
CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)scanfAndSend,NULL,NULL,NULL);
char buff[256];
int n = 0;
while (1)
{
r = recv(sSocket,buff,255,NULL); // 循环从服务器接收
if (r>0)
{
buff[r] = 0;// 添加结束符号
// 显示到图形界面窗口
outtextxy(1,n*20,buff);
n++;
if (n>18)
{
n = 0;
cleardevice(); //清屏
}
}
}
while (1);
return 0;
}
void scanfAndSend()
{
// 5. 通信
char buff[256];
while (1)
{
memset(buff, 0, 256); // 清空数组
printf("发送服务器信息:");
scanf_s("%s", buff, sizeof(buff)); // 从命令行窗口接收发给服务器
send(sSocket, buff, strlen(buff), NULL);
}
}
参考:文章来源:https://www.toymoban.com/news/detail-724734.html
https://www.bilibili.com/video/BV12u411r7J6/?spm_id_from=333.788.top_right_bar_window_custom_collection.content.click&vd_source=701c26bdba61a7e00f00852c31111c06文章来源地址https://www.toymoban.com/news/detail-724734.html
到了这里,关于C++ TCP通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!