基于windowns下的TCP网络通信编程

Tcp通信的三次握手和四次挥手

TCP的三次握手和四次挥手是TCP连接的建立和断开过程,确保了可靠的数据传输和连接状态的正确管理。

TCP的三次握手(TCP 链接建立):
1. 客户端发送 SYN 客户端向服务器发送一个 SYN 报文段( SYN=1 Seq=x ),表示请求建立连接。
2. 服务器发送 SYN+ACK 服务器收到 SYN 报文段后,如果同意建立连接,则会发送一个 SYN+ACK 报文段( SYN=1 ACK=x+1 Seq=y ),表示确认客户端的请求,并表示自己也想建立连接。
3. 客户端发送 ACK 客户端收到服务器的 SYN+ACK 报文段后,会发送一个确认报文段( ACK=1 ACK=y+1 Seq=x+1 ),表示确认收到服务器的确认,连接建立成功。
TCP的四次挥手(TCP 链接断开):
1. 客户端发送 FIN 客户端请求断开连接,发送一个 FIN 报文段( FIN=1 Seq=x )。
2. 服务器发送 ACK 服务器收到客户端的 FIN 报文段后,会发送一个确认报文段( ACK=1 ACK=x+1 Seq=y ),表示收到了客户端的请求,但是还有数据需要发送。
3. 服务器发送 FIN 服务器发送完所有数据后,会发送一个 FIN 报文段( FIN=1 ACK=x+1 Seq=y ),表示自己也准备断开连接。
4. 客户端发送 ACK 客户端收到服务器的 FIN 报文段后,会发送一个确认报文段( ACK=1 ACK=y+1 Seq=x+1 ),表示确认收到服务器的请求,连接断开。

通过三次握手,客户端和服务器之间建立了可靠的双向连接。而通过四次挥手,双方断开了连接,确保数据传输的可靠性和正确性。

客户端:

1. 初始化Winsock库: 在使用任何套接字编程功能之前,需要初始化 Winsock 库。可以使用 WSAStartup 函数来完成初始化。
2. 创建套接字: 使用 socket 函数创建一个套接字。指定地址族为 AF_INET,类型为 SOCK_STREAM,协议为 IPPROTO_TCP。
3. 设置服务器地址和端口: 创建一个 sockaddr_in 结构体,并设置其中的地址族、IP地址和端口号,用于连接服务器。
4. 连接服务器: 使用 connect 函数连接到服务器。将创建的套接字和服务器地址作为参数传递给 connect 函数。
5. 发送和接收数据: 使用 send 函数向服务器发送数据,并使用 recv 函数接收服务器的响应数据。
6. 关闭套接字: 使用 closesocket 函数关闭套接字。
7. 清理Winsock库: 在程序退出前,使用 WSACleanup 函数清理 Winsock 库的资源。
#include <iostream>
#include <string>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")int main() {// 初始化WinsockWSADATA wsData;WORD ver = MAKEWORD(2, 2);int wsOK = WSAStartup(ver, &wsData);if (wsOK != 0) {std::cerr << "Error: Can't initialize Winsock! Quitting" << std::endl;return 1;}// 创建socketSOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);if (clientSocket == INVALID_SOCKET) {std::cerr << "Error: Can't create socket! Quitting" << std::endl;WSACleanup();return 1;}// 连接到服务器sockaddr_in server;server.sin_family = AF_INET;server.sin_port = htons(54000);inet_pton(AF_INET, "127.0.0.1", &server.sin_addr);if (connect(clientSocket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {std::cerr << "Error: Can't connect to server! Quitting" << std::endl;closesocket(clientSocket);WSACleanup();return 1;}// 发送和接收数据char buffer[4096];std::string userInput;do {std::cout << "Enter a message: ";std::getline(std::cin, userInput);int sendResult = send(clientSocket, userInput.c_str(), userInput.size() + 1, 0);if (sendResult != SOCKET_ERROR) {// 接收服务器回复memset(buffer, 0, sizeof(buffer)); // 清空缓冲区int bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0);if (bytesReceived > 0) {std::cout << "Server response: " << std::string(buffer, bytesReceived) << std::endl;}}else {std::cerr << "Error: Send failed! Quitting" << std::endl;break;}} while (userInput != "quit");// 关闭客户端socketclosesocket(clientSocket);// 关闭WinsockWSACleanup();return 0;
}

服务端:

在Windows平台上创建TCP服务器的基本步骤:

1. 初始化Winsock库: 在使用任何套接字编程功能之前,需要初始化 Winsock 库。可以使用 WSAStartup 函数来完成初始化。
2. 创建套接字: 使用 socket 函数创建一个套接字。指定地址族为 AF_INET ,类型为 SOCK_STREAM ,协议为 IPPROTO_TCP
3. 设置服务器地址和端口: 创建一个 sockaddr_in 结构体,并设置其中的地址族、IP地址和端口号,用于绑定服务器的地址和端口。
4. 绑定地址和端口: 使用 bind 函数将套接字绑定到指定的地址和端口上。
5. 监听连接请求: 使用 listen 函数开始监听来自客户端的连接请求。
6. 接受连接: 使用 accept 函数接受客户端的连接请求,并创建一个新的套接字用于与客户端通信。在接受连接之前,服务器会阻塞在这一步,直到有客户端连接上来。
7. 接收和发送数据: 使用新创建的套接字进行数据的接收和发送。可以使用 recv 函数接收来自客户端的数据,使用 send 函数发送数据给客户端。
8. 关闭连接: 当通信完成后,使用 closesocket 函数关闭与客户端的连接。
9. 关闭服务器套接字: 当服务器不再接受新的连接时,使用 closesocket 函数关闭服务器套接字。
#include <iostream>
#include <string>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")int main() {// 初始化WinsockWSADATA wsData;WORD ver = MAKEWORD(2, 2);int wsOK = WSAStartup(ver, &wsData);if (wsOK != 0) {std::cerr << "Error: Can't initialize Winsock! Quitting" << std::endl;return 1;}// 创建socketSOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);if (serverSocket == INVALID_SOCKET) {std::cerr << "Error: Can't create socket! Quitting" << std::endl;WSACleanup();return 1;}// 绑定地址和端口sockaddr_in hint;hint.sin_family = AF_INET;hint.sin_port = htons(54000);hint.sin_addr.S_un.S_addr = INADDR_ANY; // 监听所有网卡上的连接bind(serverSocket, (sockaddr*)&hint, sizeof(hint));// 开始监听listen(serverSocket, SOMAXCONN);// 接受连接sockaddr_in client;int clientSize = sizeof(client);SOCKET clientSocket = accept(serverSocket, (sockaddr*)&client, &clientSize);// 关闭服务器socketclosesocket(serverSocket);// 接收和发送数据char buffer[4096];while (true) {memset(buffer, 0, sizeof(buffer)); // 清空缓冲区int bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0);if (bytesReceived == SOCKET_ERROR) {std::cerr << "Error in recv(). Quitting" << std::endl;break;}if (bytesReceived == 0) {std::cout << "Client disconnected" << std::endl;break;}std::cout << "Received: " << std::string(buffer, 0, bytesReceived) << std::endl;// Echo回消息给客户端send(clientSocket, buffer, bytesReceived, 0);}// 关闭客户端socketclosesocket(clientSocket);// 关闭WinsockWSACleanup();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/825579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI讲师人工智能讲师大模型培训讲师叶梓:突破大型语言模型推理效率的创新方法

大型语言模型&#xff08;LLM&#xff09;在自然语言处理&#xff08;NLP&#xff09;任务中展现出了前所未有的能力&#xff0c;但它们对计算资源的巨大需求限制了其在资源受限环境中的应用。SparQ Attention算法提出了一种创新的方法&#xff0c;通过减少注意力机制中的内存带…

探索Java世界中的七大排序算法(上)

文章目录 排序的概念直接插入排序希尔排序( 缩小增量排序)选择排序堆排序冒泡排序 在计算机科学中&#xff0c;排序算法是一类重要的算法&#xff0c;它们用于将一组元素按照一定的顺序进行排列。在Java编程中&#xff0c;我们经常需要对数组或集合进行排序操作。本文将介绍Jav…

驱动云创建保存自己的环境

驱动云创建保存自己的环境 制作镜像方法一方法二报错 上一篇link介绍了如何在驱动云上部署llama2以及驱动云在训练大模型的方便之处。也说到了可以直接使用驱动云现有的环境&#xff0c;免得自己配置环境。 但是有的时候免不了自己想要安装一些包。 驱动云的环境是这样的&…

电视音频中应用的音频放大器

电视机声音的产生原理是将电视信号转化为声音&#xff0c;然后通过扬声器将声音播放出来。当我们打开电视并选择频道时&#xff0c;电视机首先从天线或有线电视信号中获取声音信号。声音信号经过放大器放大之后&#xff0c;就能够通过扬声器发出声音。电视机声音的产生原理和音…

react中子父组件互相传值

在react中父子组件互相传值&#xff0c;除了使用类似于redux这样状态管理的工具&#xff0c;怎么实现&#xff1f;&#xff1f; 父传子(简单)父:子: 子传父(较麻烦)父&#xff1a;子&#xff1a; 父传子(简单) 父: 子: 子传父(较麻烦) 父&#xff1a; 子&#xff1a;

elementui中文官网

Element - The worlds most popular Vue UI frameworkElement&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.eleme.cn/#/zh-CN/

一个 .net 8 + Azure 登录 + Ant Design Blazor 的基本后台框架

一个 .net 8 Azure 登录 Ant Design Blazor 的基本后台框架 主界面使用了 Ant Design Blazor 项目模板搭建 后台技术是 .net 8 Blazor run at server 模式 登录方式使用 Azure 实现了菜单导航和路由 此外实现了读取和修改本地Json文件的功能&#xff0c;不是必须的&#x…

[MySQL数据库] 索引与事务

1. 索引 1.1 概念 索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针.可以对表中的一列或多列创建索引,并指定索引的类型&#xff0c;各类索引有各自的数据结构实现. 1.2 作用 数据库中的表、数据、索引之间的关系&#xff0c;类似于书架上的图书、书籍…

【力扣】148. 排序链表

148. 排序链表 题目描述 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4] 示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,…

深度学习架构(CNN、RNN、GAN、Transformers、编码器-解码器架构)的友好介绍。

一、说明 本博客旨在对涉及卷积神经网络 &#xff08;CNN&#xff09;、递归神经网络 &#xff08;RNN&#xff09;、生成对抗网络 &#xff08;GAN&#xff09;、转换器和编码器-解码器架构的深度学习架构进行友好介绍。让我们开始吧&#xff01;&#xff01; 二、卷积神经网络…

【观察】容器化部署“再简化”,云原生体验“再升级”

自2013年云原生概念被提出以来&#xff0c;云原生技术和架构在过去十多年得到了迅速的发展&#xff0c;并对数字基础设施、应用架构和应用构建模式带来了深刻的变革。根据IDC预测&#xff0c;到2024年&#xff0c;新增的生产级云原生应用在新应用的占比将从2020年的10%增加到60…

Java学习-详述main方法、可变参数、数组的工具类、二维数组

详述main方法 【1】main方法&#xff1a;程序的入口&#xff0c;在同一个类中&#xff0c;如果有多个方法&#xff0c;那么虚拟机就会识别main方法&#xff0c;从这个方法作为程序的入口 【2】main方法格式严格要求&#xff1a; public static void main(String[] args){} p…

线性代数---行列式的性质

1. 行列式的行与列(按原顺序)互换

SpringCloud +UniApp技术开发saas模式的智慧工地云平台源码,支持可视化大屏端、手机端、平板端、PC端

基于微服务架构JavaSpring Cloud UniApp MySql技术开发saas模式的一套智慧工地云平台源码&#xff0c;支持多端展示&#xff1a;可视化大屏端、手机端、平板端、PC端。 智慧工地平台支持项目级、公司级、集团级多级权限划分&#xff0c;可根据企业的组织架构进行项目权限、功能…

编程入门(四)【计算机网络基础(由一根网线连接两个电脑开始)】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言两个电脑如何互连呢&#xff1f;集线器、交换机与路由器总结 前言 当你有…

【opencv】dnn示例-speech_recognition.cpp 使用DNN模块结合音频信号处理技术实现的英文语音识别...

模型下载地址&#xff1a; https://drive.google.com/drive/folders/1wLtxyao4ItAg8tt4Sb63zt6qXzhcQoR6 终端输出&#xff1a;&#xff08;audio6.mp3 、audio10.mp3&#xff09; [ERROR:00.002] global cap_ffmpeg_impl.hpp:1112 open VIDEOIO/FFMPEG: unsupported parameter…

华为手机p70即将上市,国内手机市场或迎来新局面?

4月15日&#xff0c;华为官宣手机品牌全新升级&#xff0c;p系列品牌升级为Pura。华为P70系列手机预计将于2024年第一季度末发布&#xff0c;而网友也纷纷表示期待p70在拍照、性能上的全新突破。 网友们对华为P70系列的热情高涨&#xff0c;也印证了国内高端手机市场的潜力巨大…

MySql安装(Linux)

一、清除原来的mysql环境 在前期建议使用root用户来进行操作&#xff0c;使用 su -来切换成root用户&#xff0c;但是如果老是提示认证失败&#xff0c;那么有可能我们的root密码并没有被设置&#xff0c; 我们可以先设置root的密码 sudo passwd root 然后就可以切换了。 …

Mac 利用Homebrew安装JDK

一、安装JDK17 1.安装openjdk17 2.把homebrew安装的openjdk17软链接到系统目录&#xff1a; brew install openjdk17 sudo ln -sfn $(brew --prefix)/opt/openjdk17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk 一、检查是否安装成功 在Termina…

深入解析Apache Hadoop YARN:工作原理与核心组件

什么是YARN&#xff1f; YARN&#xff08;Yet Another Resource Negotiator&#xff09;是Apache Hadoop生态系统中的一个重要组件&#xff0c;用于资源管理和作业调度。它是Hadoop 2.x版本中的一个关键特性&#xff0c;取代了旧版本中的JobTracker和TaskTracker。YARN的设计目…