C++11实现计算机网络中的TCP/IP连接(Windows端)
目录
- 引言
- 1、TCP
- 2、IP
- 2.1 IP路由器
- 3、TCP/IP
- 4、TCP/IP协议C++11实现
- 参考文献
引言
TCP/IP
指传输控制协议/网际协议(Transmission Control Protocol / Internet Protocol)
。[1]
在TCP/IP协议簇中主要包含以下内容:
- TCP (传输控制协议) - 应用程序之间通信
- UDP (用户数据报协议) - 应用程序之间的简单通信
- IP (网际协议) - 计算机之间的通信
- ICMP (因特网消息控制协议) - 针对错误和状态
- DHCP (动态主机配置协议) - 针对动态寻址
TCP/IP 定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准。
1、TCP
TCP 用于应用程序之间的通信。
TCP使用固定的连接,会建立一个全双工的通信。
会占用两个计算机之间通信线路,直到被一方或者双方关闭。
2、IP
IP是计算机之间的通信。
IP是无连接的通信协议,不会占用两个正在通信计算机之间的通信线路。
因此IP降低对网络线路的需求,每条线可以同时满足不同计算机之间的通信需要。
2.1 IP路由器
IP包从一台计算机被发送,它会到达一个IP路由器。
IP路由器会路由这个IP包到它的目的地,直接地或者通过其它路由器。
相同通信,一个包经过的路径可能和其它包不同,而路由器会根据通信量
、网络中错误
或其它参数
进行正确寻址。
3、TCP/IP
TCP/IP是不同通信协议的大集合。
[1]
TCP(应用程序与应用程序之间建立的全双工通信协议),IP(计算机与计算机之间建立的通信协议)。
- TCP负责将数据分割装入IP包,然后在到达的时候重新组合它们。
- IP则在中间负责将包发送至接受者。
如下图表示:
IP地址:计算机的“门牌”号,有了IP地址才可以接入因特网。IP包就像快递,得知道IP地址才能发送到对应的计算机。
TCP/IP使用4组数字为计算机编址,每个计算机有唯一的4组数字地址。每组数字必须在0~255之间
,并用点号分割开,这里使用的是ipv4协议
。
为什么TCP/IP每个地址是使用0~255之间数字?
因为规定TCP/IP协议使用32个bit编址,在计算机中 8bit=1byte=1B,所以使用四个字节来编址。
然后8bit = 8 位,因此每组地址的范围就是
0000 0000 ~ 1111 1111,范围是0 ~ 2^8 - 1,也就是0 ~ 255。
TCP/IP简化了OSI的七层模型为四层模型。
- 优化结构。
- 每层独立但又因为上层协议使用下层协议服务,之间又存在联系。
4、TCP/IP协议C++11实现
Linux下网络编程主要分为四个步骤[2]。
- 1、调用 socket 函数创建套接字。
- 2 、调用 bind 函数分配IP地址和端口号。
- 3、调用 listen 函数转换为可接受请求状态。
- 4、调用 accept 函数受理套接字请求。
套接字
是通信中两个网路应用程序进行通信时,各自连接中的端点[3]。是通信的基石。
套接字socket表示方法是(ip地址:端口号)或(ip地址,端口号)。每一个传输层连接唯一地被通信两端的两个端点(即两个套接字)所确定。例如:如果IP地址是210.37.145.1,而端口号是23,那么得到套接字就是(210.37.145.1:23)[4]
上面引用[2]里描述的整个流程是这样的,比喻为打电话。
首先需要安装电话机,因此使用套接字socket,然后分配端口号,也就是电话号码,使用bind函数给创建号的套接字分配ip地址和端口信息。有了电话和电话号码之后,需要架设电话线,使用listen函数让这台电话可用,这时其他人可以打电话到这台电话机,电话机响的时候需要接听,最后使用accept函数来保持监听。
那么我们就简单来实现一个hello world在windows下的传输。
首先我们需要建立一个服务端项目,它能够在收到信息时进行回传hello world。
- 服务端的职能:
建立socket
,声明自身的端口号和地址并绑定到socket,使用listen
打开监听,然后不断用accept
去查看是否有连接,如果有,捕获socket,并通过recv获取消息
的内容,通信完成后调用closeSocket关闭这个对应accept到的socket
,如果不再需要等待任何客户端连接,那么用closeSocket关闭掉自身的socket。 - 客户端职能:建立socket套接字,通过ip地址和端口号确定目标服务器。使用
connect
连接服务器,使用send
函数发送消息,等待服务器处理,通信完成后调用closeSocket
关闭socket。
参考这位朋友的博客[5]实现了基本的服务端架设,服务端代码和注释转载于(初学者的福音)windows下实现socket通信(TCP/IP)代码详解——服务端篇。
/*****************************************************************************************************************************
* 1、加载套接字库,创建套接字(WSAStartup()/socket());
* 2、绑定套接字到一个IP地址和一个端口上(bind());
* 3、将套接字设置为监听模式等待连接请求;
* 4、请求到来之后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
* 5、用返回的套接字和客户端进行通信(send()/recv());
* 6、返回,等待另一个连接请求
* 7、关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup());
*****************************************************************************************************************************/
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<WinSock2.h>
using namespace std;
#pragma comment(lib,"ws2_32.lib")int main()
{//初始化WSAWORD sockVersion = MAKEWORD(2, 2);WSADATA wsaData;//WSADATA结构体变量的地址值//int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);//成功时会返回0,失败时返回非零的错误代码值if (WSAStartup(sockVersion, &wsaData) != 0){cout << "WSAStartup() error!" << endl;return 0;}//创建套接字SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (slisten == INVALID_SOCKET){cout << "socket error !" << endl;return 0;}//绑定IP和端口sockaddr_in sin;//ipv4的指定方法是使用struct sockaddr_in类型的变量sin.sin_family = AF_INET;sin.sin_port = htons(8888);//设置端口。htons将主机的unsigned short int转换为网络字节顺序sin.sin_addr.S_un.S_addr = INADDR_ANY;//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址//bind函数把一个地址族中的特定地址赋给scket。if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR){printf("bind error !");}//开始监听if (listen(slisten, 5) == SOCKET_ERROR){cout << "listen error !" << endl;return -1;}//循环接收数据SOCKET sclient;sockaddr_in remoteAddr;//sockaddr_in常用于socket定义和赋值,sockaddr用于函数参数int nAddrlen = sizeof(remoteAddr);char revData[255];while (true){cout << "等待连接。。。" << endl;sclient = accept(slisten, (sockaddr*)&remoteAddr, &nAddrlen);if (sclient == INVALID_SOCKET){cout << "accept error !" << endl;continue;}cout << "接收到一个连接:" << inet_ntoa(remoteAddr.sin_addr) << endl;//接收数据int ret = recv(sclient, revData, 255, 0);if (ret > 0){revData[ret] = 0x00;cout << revData << endl;}//发送数据const char* sendData = "你好,TCP客户端!\n";send(sclient, sendData, strlen(sendData), 0);closesocket(sclient);}closesocket(slisten);WSACleanup();system("pause");//return 0;
}
客户端实现,客户端代码来源于windows环境下用c++实现socket编程:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WINSOCK2.H>
#include<STDIO.H>
#include<iostream>
#include<cstring>
using namespace std;
#pragma comment(lib, "ws2_32.lib")int main()
{WORD sockVersion = MAKEWORD(2, 2);WSADATA data;if (WSAStartup(sockVersion, &data) != 0){return 0;}while (true) {SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sclient == INVALID_SOCKET){printf("invalid socket!");return 0;}sockaddr_in serAddr;serAddr.sin_family = AF_INET;serAddr.sin_port = htons(8888);serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");if (connect(sclient, (sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR){ //连接失败 printf("connect error !");closesocket(sclient);return 0;}string data;cin >> data;const char* sendData;sendData = data.c_str(); //string转const char* //char * sendData = "你好,TCP服务端,我是客户端\n";send(sclient, sendData, strlen(sendData), 0);//send()用来将数据由指定的socket传给对方主机//int send(int s, const void * msg, int len, unsigned int flags)//s为已建立好连接的socket,msg指向数据内容,len则为数据长度,参数flags一般设0//成功则返回实际传送出去的字符数,失败返回-1,错误原因存于error char recData[255];int ret = recv(sclient, recData, 255, 0);if (ret > 0) {recData[ret] = 0x00;printf(recData);}closesocket(sclient);}WSACleanup();return 0;}
先运行服务端,再运行客户端,然后输入内容,便可以通过TCP/IP传输。
最终结果:
后续解析待更新。。。
参考文献
[4] 潘伟编著,计算机网络 理论与实验,厦门大学出版社,2013.12,第145页
相关文章:
C++11实现计算机网络中的TCP/IP连接(Windows端)
目录引言1、TCP2、IP2.1 IP路由器3、TCP/IP4、TCP/IP协议C11实现参考文献引言 TCP/IP 指传输控制协议/网际协议(Transmission Control Protocol / Internet Protocol)。[1] 在TCP/IP协议簇中主要包含以下内容: TCP (传输控制协议) - 应用程序…...
Spring框架自定义实现IOC基础功能/IDEA如何手动实现IOC功能
继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库Java设计模式克隆下载学习使用! 7.4 自定义Spring IOC 创建新模块,结构如图![[Pasted image 20230210173222.png]] 7.4.1 定义bean相关POJO类 7.4.1.1 定义propertyValue类 /** …...
pip离线安装windows版torch
文章目录前言conda创建虚拟环境安装torchtorch官网在线安装离线手动安装测试是否安装成功后记前言 学习的时候遇到几个机器学习相关的项目,由于不同的项目之间用到的依赖库不太一样,于是想利用conda为不同的项目创建不同的环境方便管理和运行࿰…...
Redis核心知识点
Redis核心知识点Redis核心知识点大全五种数据类型redis整合SpringBoot序列化问题渐进式扫描慢查询缓存相关问题数据库和缓存谁先更新缓存穿透缓存雪崩缓存击穿实际应用超卖问题分布式锁全局唯一ID充当消息队列Feed流附近商户签到HyperLogLog实现UV统计持久化RDBAOF持久化小结事…...
14. 最长公共前缀
14. 最长公共前缀 一、题目描述: 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例 1: 输入:strs [“flower”,“flow”,“flight”] 输出:“fl” 示例 2: …...
SignalR注册成Windows后台服务,并实现web前端断线重连
注意下文里面的 SignalR 不是 Core 版本,而是 Framework 下的 本文使用的方式是把 SignalR 写在控制台项目里,再用 Topshelf 注册成 Windows 服务 这样做有两点好处 传统 Window 服务项目调试时需要“附加到进程”,开发体验比较差…...
【前端笔试题二】从一个指定数组中,每次随机取一个数,且不能与上次取数相同,即避免相邻取数重复
前言 本篇文章记录下我在笔试过程中遇到的真实题目,供大家参考。 1、题目 系统给定一个数组,需要我们编写一个函数,该函数每次调用,随机从该数组中获取一个数,且不能与上一次的取数相同。 2、思路解析 数组已经有了…...
专栏关注学习
Node学习专栏(全网最细的教程) 【spring系列】 SpringCloud 前端框架Vue java学习过程 RocketMQ Spring Tomcat websocket 从头开始学Redisson 从头开始学Oracle 跟着大宇学Shiro 吃透Shiro源代码 Git基础与进阶 Java并发编程 Spring系列 手写…...
【手写 Vuex 源码】第八篇 - Vuex 的 State 状态安装
一,前言 上一篇,主要介绍了 Vuex 模块安装的实现,针对 action、mutation、getter 的收集与处理,主要涉及以下几个点: Vuex 模块安装的逻辑;Vuex 代码优化;Vuex 模块安装的实现;Vue…...
Mac下拉式终端的安装与配置 (iTerm2)
Mac下拉式终端的安装与配置 使用效果如图所示 安装前置软件 iTerm2 很可惜,如此炫酷的功能在原终端中并不能实现,我们需要借助iTerm2这个软件来实现。 官网链接:iTerm2 - macOS Terminal Replacement 我们点击download下载即可 配置 当我…...
使用 Spring 框架结合阿里云 OSS 实现文件上传的代码示例
使用 Spring 框架结合阿里云 OSS 实现文件上传的代码示例POM文件配置文件上传工具类控制层使用yaml配置文件(第二种用法,看公司要求)注入 OSSClient 对象及工具类(第二种用法,看公司要求)使用 Vue 前端代码…...
神经网络基础知识
神经网络基础知识 文章目录神经网络基础知识一、人工神经网络1.激活函数sigmod函数Tanh函数Leaky Relu函数分析2.过拟合和欠拟合二、学习与感知机1.损失函数与代价函数2. 线性回归和逻辑回归3. 监督学习与无监督学习三、优化1.梯度下降法2.随机梯度下降法(SGD)3. 批量梯度下降法…...
SpringBoot开发规范部分通用模板+idea配置【项目通用-1】
SpringBoot开发规范通用模板 1 分页插件使用 通过MybatisPlus配置分页插件拦截器 Configuration MapperScan("com.xuecheng.content.mapper") //拦截的mapper层 public class MybatisPlusConfig {//定义分页的拦截器Beanpublic MybatisPlusInterceptor getMybatisPl…...
程序的机器级表示part3——算术和逻辑操作
目录 1.加载有效地址 2. 整数运算指令 2.1 INC 和 DEC 2.2 NEG 2.3 ADD、SUB 和 IMUL 3. 布尔指令 3.1 AND 3.2 OR 3.3 XOR 3.4 NOT 4. 移位操作 4.1 算术左移和逻辑左移 4.2 算术右移和逻辑右移 5. 特殊的算术操作 1.加载有效地址 指令效果描述leaq S, DD…...
基于YOLOV5的钢材缺陷检测
数据和源码见文末 1.任务概述 数据集使用的是东北大学收集的一个钢材缺陷检测数据集,需要检测出钢材表面的6种划痕。同时,数据集格式是VOC格式,需要进行转化,上传的源码中的数据集是经过转换格式的版本。 2.数据与标签配置方法 在数据集目录下,train文件夹下有训练集数据…...
Session与Cookie的区别(三)
中场休息 让我们先从比喻回到网络世界里,HTTP 是无状态的,所以每一个 Request 都是不相关的,就像是对小明来说每一位客人都是新的客人一样,他根本不知道谁是谁。 既然你没办法把他们关联,就代表状态这件事情也不存在。…...
七大设计原则之接口隔离原则应用
目录1 接口隔离原则介绍2 接口隔离原则应用1 接口隔离原则介绍 接口隔离原则(Interface Segregation Principle, ISP)是指用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接口。这个原则指导我们在设计接口时…...
【Shell1】shell语法,ssh/build/scp/upgrade,环境变量,自动升级bmc
文章目录1.shell语法:shell是用C语言编写的程序,是用户使用Linux的桥梁,硬件>内核(os)>shell>文件系统1.1 变量:readonly定义只读变量,unset删除变量1.2 函数:shell脚本传递的参数中包含空格&…...
JavaScript HTML DOM - 改变CSS
JavaScript 是一种动态语言,它可以动态地修改网页的外观,并且使用HTML DOM(文档对象模型)可以更方便地控制HTML元素的样式。 JavaScript 通过在HTML DOM中更改CSS属性来更改样式,这些CSS属性包括颜色、位置、字体大小…...
mycat连接mysql 简单配置
mycat三个配置文件位于conf下 可通过Notepad操作 首先配置service.xml中的user标签,设置用户名,密码,查询权限,是否只读等 只是设置了root用户,有所有权限 配置schema.xml <?xml version"1.0"?&g…...
Spring常用注解
文章目录一、Bean交给Spring管理1、Component2、Bean3、Controller4、Service5、Repository6、Configuration7、ComponentScan二、作用域1、Lazy(false)Scope三、依赖注入1、Autowired2、Resource3、Qualifier四、读取配置文件值1、Value一、Bean交给Spring管理 1、Component …...
I.MX6ULL内核开发9:kobject-驱动的基石
目录 一、摘要 二、重点 三、驱动结构模型 四、关键函数分析 kobject_create_and_add()函数 kobject_create()函数 kobject_init()函数 kobject_init_internal()函数 kobject_add()函数 kobject_add_varg&am…...
Docker-harbor私有仓库
一、Harbor概述 1、Harbor的概念 • Harbor是VMware公司开源的企业级Docker Registry项目,其目标是帮助用户迅速搭建一个企业级的Docker Registry服务 • Harbor以 Docker 公司开源的Registry 为基础,提供了图形管理UI、基于角色的访问控制(Role Base…...
Java之动态规划之子序列问题
目录 0.动态规划问题 一.最长递增子序列 1.题目描述 2.问题分析 3.代码实现 二.最长递增子序列 1.题目描述 2.问题分析 3.代码实现 三.最长重复子数组 1.题目描述 2.问题分析 3.代码实现 4.代码的优化(滚动数组) 四.最长公共子序列 1.题目描述 2.问题分析 3.代…...
java ArrayList
目录 一.简单介绍 二.ArrayList的底层结构 2.1ArrayList的底层结构和操作分析 2.ArrayList 底层源码分析 三.ArrayList 方法 四.代码使用方法 一.简单介绍 ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们…...
前端——周总结系列四
1 JS变量与常量 概述 变量:在后续编码过程中会被重新赋值,是不断变化的。常量:固定不变的数据,日常生活比如性别男,代码层面是在编码过程中不会变化的固定数据。 命名规则 变量 可以包含数字,字母&…...
Linux重定向符、管道符讲解
目录 重定向 将命令与文件进行互动 输出重定向 输入重定向 管道符 将命令与命令互动起来 重定向 将命令与文件进行互动 重定向分类 一般情况下,Linux命令运行时都会打开一下三个文件 标准输入文件:stdin文件,文件描述符为0,Li…...
【C++】多态
多态一、多态的概念及定义1.1 虚函数1.2 虚函数重写的特殊情况1.3 override 和 final二、抽象类2.1 概念2.2 用处三、多态的原理3.1 虚函数表3.1.1 虚函数与虚表的位置3.2 多态的原理3.3 静态绑定和动态绑定四、单/多继承的虚函数表4.1 单继承的虚函数表4.2 多继承的虚函数表一…...
分布式项目-品牌管理(5、6)
【今日成果】: //使用阿里云OSS服务: //使用v-if如果地址没有就不显示 , 如果地址错误图片就显示不出来; 【快速回顾】: 任何数据的删除都不要使用物理上的删除,应当使用逻辑上的删除!&…...
自定义ESLint规则开发与使用
自定义eslint及使用 项目结构 |-eslint-plugin-demo //自定义eslint插件项目 | |-demo-app // 使用自定义eslint的测试应用 |-README.md 项目效果: github项目地址 自定义ESLint环境准备 安装脚手架 执行下列命令来安装开发eslint的脚手架。 yo(y…...
外国小孩和大人做网站/正规代运营公司排名
本书的作用 本书会帮助你跨过“原理听起来不错,但还是有点儿新,不太适应”的门槛,从而熟练地编程。 “也许吧,”你可能会想,“可是Lambda、函数式编程,这些不是那些留着胡子、穿着凉鞋的学究们在象牙塔里面…...
前端做网站都要做哪些/seo排名优化联系13火星软件
Description有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小。Input第一行为3个整数,分别表示a,b,n的值第二行至第a1行每行为b个非负整数,表示矩阵中相应位置上的数。每…...
做网站 搞流量 赚广告费/百度客户端
1.哪里会有人喜欢孤独,不过是不喜欢失望罢了。 —— 《挪威的森林》 2.我一直以为人是慢慢变老的,其实不是,人是一瞬间变老的。 —— 《舞!舞!舞!》 3.每个人都有属于自己的一片森林,也许我…...
太原商城网站建设/网络营销策划书的结构是什么
随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666) 我们都知道Node.js现在得到了所有的关注。每个人都对学习Node.js感兴趣,并希望可以工作于Node.js。在开始工作之前了解技术背后的概念总是不会错的。…...
iis7搭建网站织梦/宁波seo推广联系方法
省市级联//定义一个保存所有城市的数组var arys [["北京","天津","重庆","上海"],["长沙","株洲","湘潭","娄底","岳阳"],["东莞","佛山","中山",…...
网站建设的步骤/今日头条官网
如果要给C11颁一个“最令人困惑新词”奖,constexpr十有八九会折桂。当用于对象上面,它本质上就是const的加强形式,但是当它用于函数上,意思就大不相同了。有必要消除困惑,因为你绝对会用它的,特别是当你发现…...