基于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;通过减少注意力机制中的内存带…

TCP为什么需要3次握手?

一、3次握手过程 客户端向服务端发送一个表示建立连接的SYN报文段&#xff0c;服务端从IP数据报中提取出TCP SYN报文段&#xff0c;为该TCP连接分配需要的缓存和变量&#xff0c;并向客户端发送表示允许连接的报文段ACK。客户端在收到ACK报文段之后&#xff0c;也要给该连接分配…

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

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

【docker 】docker-compose 部署mongoDB

在notepad中将格式改为UNIX &#xff08;编辑》文档格式转化》转为Unix&#xff09;&#xff0c;编码改为UTF-8 &#xff08; 编码》转为UTF-8&#xff09;&#xff0c;改好后如图 新建启动脚本 mongo.sh #!/bin/bash # 挂载路径 DATA_DIR/opt/docker-data/mongodb/data LOG_…

timesten 安装

1. 安装 从oracle的网站&#xff08;http://www.oracle.com/technology/global/cn/software/products/timesten/index.html&#xff09;下载&#xff0c;timesten的安装文件。 将下载文件解压后&#xff0c;出现linux86文件夹&#xff0c;执行setup.sh&#xff0c;步骤如下…

死磕GMSSL通信-java/Netty系列(三)

死磕GMSSL通信-java/Netty系列&#xff08;三&#xff09; 接着上次的博客继续完善&#xff0c;上次其实只是客户端的改造&#xff0c;这次把服务端的也补上&#xff0c;netty集成GMSSL实现GMServer 1、netty_tcnative c代码改造&#xff0c;这个是客户端和服务端都需要都该的…

数据挖掘与机器学习

一. 机器学习的种类 1. 有监督的机器学习 : 分类 : KNN 最近邻 逻辑回归 - 朴素贝叶斯估计 SVM 线性 或 非线性 优化模型 决策树模型 - 随机森林 - 其它集成模型 lightGBM - XGBOOST 回归: 线性 …

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

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

基于SpringBoot + Vue 的电影售票及影院管理系统(前后端分离)

后端&#xff1a;Spring Boot Mybatis 实现功能&#xff1a; 售票子系统&#xff1a;用户浏览电影信息&#xff0c;电影分类查看&#xff0c;搜索查看&#xff0c;购票操作&#xff08;未实现支付沙箱&#xff09;&#xff0c;超时取消订单等 管理子系统&#xff1a;管理员…

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

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

react中子父组件互相传值

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

面试话术1

自我介绍 面试官您好&#xff01;我叫王鹏宇&#xff0c;本科是在西南石油大学读的&#xff0c;是一所双一流大学。我本人对网络安全领域比较有兴趣的&#xff0c;并且想对国家网络安全建设做出贡献。我去年也参加了护网&#xff0c;在那边主要就是负责流量研判&#xff0c;然…

机器学习在基因组学中的应用

机器学习在基因组学中的应用 李升伟1 茅 矛1 陈 竺2 &#xff08;1.特趣生物科技有限公司&#xff0c;广东省深圳市&#xff1b;2.上海交通大学医学院附属瑞金医院&#xff0c;上海市&#xff09; 机器学习在基因组学中的应用已经变得日益重要和普遍&#xff0c;其核心价…

elementui中文官网

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

android gradle引入其他gradle文件

在Android项目中&#xff0c;如果你想在一个Gradle文件中引入另一个Gradle文件&#xff0c;你可以使用apply from语句。以下是一个简单的例子&#xff1a; 假设你有一个通用的Gradle配置脚本common.gradle&#xff0c;它位于项目的根目录下。 common.gradle 文件内容示例&…

一个 .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…

搭建Bootstrap5+Webpack项目

我是个前端菜鸡&#xff0c;最近准备学习一点前端知识&#xff0c;先从Bootstrap5开始&#xff0c;毕竟早期Bootstrap还是比较火的。推出的Bootstrap5不再和jQery强制绑定&#xff0c;这里直接按照官方文档上来操作&#xff0c;打包工具我们选择Webpack。 一 前期准备 前期准备…

[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; 二、卷积神经网络…