windows系统编程2——内存管理和网络( 三 )


3、第 3 次分手:主机 2 向主机 1 发送 FIN 报文段 , 请求关闭连接 , 同时主机 2 进入状态;
4、第 4 次分手:主机 1 收到主机 2 发送的 FIN 报文段 , 向主机 2 发送 ACK 报文段 , 然后主机 1 进入 TIME_ WAIT 状态;主机 2 收到主机 1 的 ACK 报文段以后 , 就关闭连接;此时 , 主机 1 等待 2MSL 后依然没有收到回复 , 则证明端已正常关闭 , 那好 , 主机 1 也可以关闭连接了
2.5TCP服务器/客户端创建过程
2.6UDP服务器/客户端创建过程
三、测试 TCP 3.1 测试连接
1、头文件
#ifndef _SOCKET_INIT_H_#define _SOCKET_INIT_H_#pragma once#pragma comment(lib, "ws2_32.lib")#include #include class SocketInit {public:SocketInit() {WORD sockVersion = MAKEWORD(2, 2);WSADATA wasData;if (WSAStartup(sockVersion, &wasData) != 0) {printf("动态链接库加载失败!\n");}}~SocketInit() {WSACleanup();}};#endif // !_SOCKET_INIT_H_
2、服务端
#include "SocketInit.hpp"using namespace std;int main(){SocketInit socketInit;// 加载动态库// 创建监听套接字SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sListen == SOCKET_ERROR) {printf("监听套接字创建失败!\n");return -1;}sockaddr_in sock_in;sock_in.sin_family = AF_INET;// 协议族sock_in.sin_port = htons(12306);// 端口号sock_in.sin_addr.S_un.S_addr = INADDR_ANY; // 获取本机的IP地址// 绑定套接字int ret = bind(sListen, (const sockaddr*)&sock_in, sizeof(sockaddr_in));if (ret == SOCKET_ERROR) {printf("绑定套接字失败!\n");closesocket(sListen);return -1;}// 监听if (listen(sListen, 10) == SOCKET_ERROR) {printf("监听失败!\n");closesocket(sListen);return -1;}sockaddr_in clientAddr;int nlen = sizeof(sockaddr_in);// 接受客户端的连接SOCKET sClient = accept(sListen, (sockaddr*)&clientAddr, &nlen);if (sClient == SOCKET_ERROR) {printf("接收客户端失败!\n");closesocket(sListen);return -1;}printf("与客户端建立连接...\n");getchar();return 0;}
3、客户端
#include "SocketInit.hpp"using namespace std;int main(){SocketInit socketInit;// 加载动态库// 创建监听套接字SOCKET sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sClient == SOCKET_ERROR) {printf("监听套接字创建失败!\n");return -1;}sockaddr_in sock_in;sock_in.sin_family = AF_INET;// 协议族sock_in.sin_port = htons(12306);// 端口号sock_in.sin_addr.S_un.S_addr = inet_addr("192.168.3.165");if (connect(sClient, (const sockaddr*)&sock_in, sizeof(sock_in)) == SOCKET_ERROR) {printf("连接服务器失败!\n");return -1;}getchar();return 0;}
过程如果报错 , 可以使用的解决方法:
(4条消息) C4996: '': Use () or ()or小哈龙的博客-CSDN博客
先打开服务端 , 然后再打开客户端 , 运行结果:
3.2 测试收发数据
#include "SocketInit.hpp"using namespace std;int main(){SocketInit socketInit;// 加载动态库// 创建监听套接字SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sListen == SOCKET_ERROR) {printf("监听套接字创建失败!\n");return -1;}sockaddr_in sock_in;sock_in.sin_family = AF_INET;// 协议族sock_in.sin_port = htons(12306);// 端口号sock_in.sin_addr.S_un.S_addr = INADDR_ANY; // 获取本机的IP地址// 绑定套接字int ret = bind(sListen, (const sockaddr*)&sock_in, sizeof(sockaddr_in));if (ret == SOCKET_ERROR) {printf("绑定套接字失败!\n");closesocket(sListen);return -1;}// 监听if (listen(sListen, 10) == SOCKET_ERROR) {printf("监听失败!\n");closesocket(sListen);return -1;}sockaddr_in clientAddr;int nlen = sizeof(sockaddr_in);// 接受客户端的连接SOCKET sClient = accept(sListen, (sockaddr*)&clientAddr, &nlen);if (sClient == SOCKET_ERROR) {printf("接收客户端失败!\n");closesocket(sListen);return -1;}printf("与客户端建立连接...\n");while (true) {char buff[1024] = { 0 };intresult = recv(sClient, buff, 1024, 0);if (result > 0) {printf("接收到的数据:%s\n", buff);}else {printf("客户端断开连接!\n");break;}}closesocket(sListen);getchar();return 0;}