网络编程基础_4.1TCP_服务端
#include <stdio.h> // 1. 包含必要的头文件和库, 必须位于 windows之前 #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") #include <windows.h> #include <ws2tcpip.h> // TCP 和 UDP 时处于传输层的两个协议 // - TCP 是一个基于连接的,安全的传输协议,实现相对复杂 // - UDP 是一个基于无连接的,不安全的传输协议,实现相对简单 // 工具函数,用于判断是否执行成功 VOID CheckResult(BOOL Value, LPCWSTR ErrMsg) { // 如果 Value 非空,就表示执行成功 if (Value == FALSE) { printf("ErrMsg: %ls\n", ErrMsg); system("pause"); ExitProcess(0); } } int main() { // 2. 初始化网络环境并判断是否成功[ 搜索信号(2G?3G?4G?) ] WSAData WsaData = { 0 }; if (!WSAStartup(MAKEWORD(2, 2), &WsaData)) CheckResult(WsaData.wVersion == 0x0202, L"初始化网络环境失败"); // 问题一: 如何确定我的数据传输给了那一台电脑 // 答: 通过 IP 地址可以找到目标计算机,IP地址的格式是 XXX.XXX.XXX.XXX // 实际上是一个4字节的整数 // 问题二: 如何确定我的数据传输给了哪一个应用 // 答: 端口,通过端口可以区分当前的数据发送给了哪一个具体的程序 // 问题三: 数据传输的过程中通常使用什么字节序 // 答: 网络传输使用的是大端,个人计算机使用的是小端,需要 // 使用 htonX 进行转换,端口的范围是 0 ~ 65535,自己 // 在定义端口的时候,尽量使用冷门的端口 // 3. 创建套接字(IP+PORT) [ 买手机 ] // - 参数一: 协议族, 表示需要进行什么类型的传输 // - 参数二: 使用的是流式套接字还是数据报套接字,原始套接字 // - 参数三,对应参数二的类型,TCP\UDP SOCKET ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); CheckResult(ServerSocket != INVALID_SOCKET, L"套接字创建失败"); // 4. 绑定套接字,提供IP和端口 (办手机卡) sockaddr_in ServerAddr = { 0 }; ServerAddr.sin_port = htons(0x1515); // 端口 ServerAddr.sin_family = AF_INET; // 协议类型 inet_pton(AF_INET, "127.0.0.1", &ServerAddr.sin_addr.S_un); BOOL Result = bind(ServerSocket, // 要绑定的套接字 (SOCKADDR*)& ServerAddr, // 服务器的地址和IP对应的结构体 sizeof(sockaddr_in)); // 必须要指定大小 CheckResult(Result != SOCKET_ERROR, L"套接字绑定失败"); // 5. 监听套接字 (开机,等待连接) // - 监听谁,最多等待多少个客户端的链接 Result = listen(ServerSocket, SOMAXCONN); // 6. 等待客户端的连接(接电话) int dwSize = sizeof(sockaddr_in); sockaddr_in ClientAddr = { 0 }; // 接收的客户端ip和端口 SOCKET ClientSocket = accept(ServerSocket, (SOCKADDR*)& ClientAddr, &dwSize); // 7. 发送数据和接收数据 CHAR Buffer[0x100] = { 0 }; // 调用成功返回值为收发的字节数,否则为 SOCKET_ERROR send(ClientSocket, "welcome", 8, 0); recv(ClientSocket, Buffer, 0x100, 0); printf("Client: %s", Buffer); // 8. 关闭套接字执行清理工作 shutdown(ClientSocket, SD_BOTH); closesocket(ClientSocket); closesocket(ServerSocket); // 9. 清理网络环境 WSACleanup(); system("pause"); return 0; }