相关文章推荐:
Socket 编程基础
面试官,不要再问我三次握手和四次挥手
TCP的三次握手与四次挥手
参考视频:
https://www.bilibili.com/video/BV1aW4y1w7Ui/?spm_id_from=333.337.search-card.all.click
TCP通信流程
服务端
#include<iostream>
#include<cstring>
#include<WinSock2.h>
#pragma comment(lib, "ws2_32.lib")using namespace std;int main(void)
{//Windows上使用网络功能需要开启网络权限WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);//1.创建socket套接字//SOCKET socket{// int af, //协议地址簇 IPV4/IPV6 AF_INET/AF_INET6// int type, //类型 流式协议/帧式协议 SOCK_STREAM/SOCK_DGRAM// int protocol //保护协议 0//};SOCKET listen_socket = socket(AF_INET, SOCK_STREAM, 0);if (listen_socket == INVALID_SOCKET) {cerr << "error" << endl;return -1;}//2.给这个socket绑定一个端口号//struct sockaddr_in {// ADDRESS_FAMILY sin_family; //协议地址簇// USHORT sin_port; //端口号// IN_ADDR sin_addr; //IP地址// CHAR sin_zero[8]; //保留字节//};struct sockaddr_in local = { 0 };local.sin_family = AF_INET;local.sin_port = htons(9999); //大小端问题 中间设备使用的是大端序(路由器)local.sin_addr.s_addr = INADDR_ANY; //表示接受任意网卡的数据 //bind(// SOCKET s,// const struct sockaddr* name,// int namelen//);if (bind(listen_socket, (struct sockaddr*)&local, sizeof local) == INVALID_SOCKET) {cerr << "error" << endl;return -1;}//3.给这个socket开启监听属性//listen(// SOCKET s,// int backlog//);if (listen(listen_socket, 128) == -1) {cerr << "error" << endl;return -1;}//4.等待客户端连接// 返回的客户端socket才是跟客户端可以通讯的socket// 阻塞函数,等到有客户端连接进来就接受连接,然后返回,否则就阻塞//accept(// SOCKET s,// struct sockaddr* addr,// int* addrlen//);while (true) {SOCKET client_socket = accept(listen_socket, nullptr, nullptr);if (client_socket == INVALID_SOCKET) {continue;}//5.开始通讯(B/S)//recv(// SOCKET s, //客户端socket// char* buf, //要接受的数据存储的位置// int len, //接受的长度// int flags //0//);//send(// SOCKET s, //客户端socket// const char* buf, //要发送的数据存储的位置// int len, //长度// int flags //0//);char buffer[1024] = { 0 };int ret = recv(client_socket, buffer, sizeof buffer, 0);cout << buffer << endl;send(client_socket, buffer, strlen(buffer), 0);//6.关闭连接closesocket(client_socket);}return 0;
}
客户端
#include<iostream>
#include<cstring>
#include<Winsock2.h>
#include<WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")using namespace std;int main(void)
{WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);//1.创建socket套接字SOCKET client_socket = socket(AF_INET, SOCK_STREAM, 0);if (client_socket == INVALID_SOCKET) {cerr << "error" << endl;return -1;}//2.连接服务器struct sockaddr_in target;target.sin_family = AF_INET;target.sin_port = htons(9999); //与服务端端口一致inet_pton(AF_INET, "127.0.0.1", &target.sin_addr.s_addr); //转换本地环回地址//target.sin_addr.s_addr = inet_addr("127.0.0.1");//connect(// SOCKET s,// const struct sockaddr* name,// int namelen//);if (connect(client_socket, (struct sockaddr*)&target, sizeof target) == INVALID_SOCKET) {cerr << "error" << endl;closesocket(client_socket);return -1;}//3.开始通讯 send recvwhile (true) {char buffer1[1024] = { 0 };cout << "enter: ";cin >> buffer1;send(client_socket, buffer1, strlen(buffer1), 0);char buffer2[1024] = { 0 };int ret = recv(client_socket, buffer2, sizeof buffer2, 0);if (ret <= 0) {break;}cout << buffer2 << endl;}//4.关闭连接closesocket(client_socket);return 0;
}
服务端完整代码
#include<iostream>
#include<cstring>
#include<WinSock2.h>
#include<thread>
#pragma comment(lib, "ws2_32.lib")using namespace std;int main(void)
{WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);SOCKET listen_socket = socket(AF_INET, SOCK_STREAM, 0);if (listen_socket == INVALID_SOCKET) {cerr << "error" << endl;return -1;}struct sockaddr_in local = { 0 };local.sin_family = AF_INET;local.sin_addr.s_addr = INADDR_ANY;local.sin_port = htons(9999);if (bind(listen_socket, (struct sockaddr*)&local, sizeof local) == INVALID_SOCKET) {cerr << "error" << endl;return -1;}if (listen(listen_socket, 128) == -1) {cerr << "error" << endl;return -1;}while (true){SOCKET client_socket = accept(listen_socket, nullptr, nullptr);if (client_socket == INVALID_SOCKET) {continue;}cout << "client connect: " << client_socket << endl; thread th([](SOCKET client_socket){while (true) {char buffer[1024] = { 0 };int ret = recv(client_socket, buffer, sizeof buffer, 0);if (ret <= 0) {cout << "client disconnect: " << client_socket << endl;break;}cout << buffer << endl;send(client_socket, buffer, strlen(buffer), 0);}closesocket(client_socket);}, client_socket);th.detach();}return 0;
}
客户端完整代码
#include<iostream>
#include<cstring>
#include<Winsock2.h>
#include<WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")using namespace std;int main(void)
{WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);SOCKET client_socket = socket(AF_INET, SOCK_STREAM, 0);if (client_socket == INVALID_SOCKET) {cerr << "error" << endl;return -1;}struct sockaddr_in target;target.sin_family = AF_INET;target.sin_port = htons(9999);inet_pton(AF_INET, "127.0.0.1", &target.sin_addr.s_addr);if (connect(client_socket, (struct sockaddr*)&target, sizeof target) == INVALID_SOCKET) {cerr << "error" << endl;closesocket(client_socket);return -1;}while (true) {char buffer1[1024] = { 0 };cout << "enter: ";cin >> buffer1;send(client_socket, buffer1, strlen(buffer1), 0);char buffer2[1024] = { 0 };int ret = recv(client_socket, buffer2, sizeof buffer2, 0);if (ret <= 0) {cout << "server disconnect." << endl;}cout << buffer2 << endl;}closesocket(client_socket);return 0;
}