基于C#的TCP/IP协议应用(一)

一、背景与概念

1.标准以太网

以太网是美国Xerox(施乐)公司的Palo Alto研究中心于1975年研制成功的,其核心技术起源于ALOHA网。目前以太网是指符合IEEE 802.3标准的局域网(LAN)产品组,其中IEEE 802.3是一组电气与电子工程师协会(IEEE)标准,用于定义有线以太网媒体访问控制的物理层和数据链路层,说明了配置以太网网络的规则,以及各种网络元件如何彼此协作。以太网分为:
1.标准以太网:早期的10Mbps以太网称之为标准以太网,是一种总线型局域网,由同轴电缆、网卡(网络适配器)组成。。
在这里插入图片描述
发送和接收数据通过CSMA/CD协议完成,流程可以简单概括为四点:先听后发,边听边发,冲突停止,延迟重发
2.总线以太网通过中继器、网桥进行扩展。
中继器(Repeater)也叫转发器,将在传输介质中衰减的信号放大,以增加线缆的传输距离。
网桥(Bridge)又称桥接器,是一种存储转发设备。它工作在数据链路层,当它收到一个帧时,先检查此帧的目的MAC地址,然后再确定将该帧转发到哪一个端口。
以太网种类繁多,包括基于集线器的以太网,基于交换机的以太网等,目前已发展到十万兆以太网。。

2.工业以太网

工业以太网一般来讲是指技术上与商用以太网(即IEEE802.3标准)兼容,但在产品设计时,在材质的选用、产品的强度、适用性以及实时性等方面能满足工业现场的需要。
目前包括4种主要协议:HSE、Modbus TCP/IP、ProfINet、Ethernet/IP。
基金会现场总线FF于2000年发布Ethernet规范,称HSE(High Speed Ethernet)。
Modbus TCP/IP协议由施耐德公司推出,以一种非常简单的方式将Modbus帧嵌入到TCP帧中,使Modbus与以太网和TCP/IP结合。
德国西门子于2001年发布了ProfiNet网络方案,它是将原有的Profibus与互联网技术结合。ProfiNet采用标准TCP/IP协议加上应用层的RPC/DCOM来完成节点间的通信和网络寻址。
Ethernet/IP是适合工业环境应用的协议体系,基于CIP(Controland Information Proto-Col)协议。它是一种是面向对象的协议,能够保证网络上隐式(控制)的实时I/O信息和显式信息(包括用于组态、参数设置、诊断等) 的有效传输。
工业以太网设备包括以下几个重要部分:
1.工业以太网集线器
2.工业以太网非管理型交换机
3.工业以太网管理型交换机
4.工业以太网管理型冗余交换机

3.TCP/IP协议

在这里插入图片描述
上表为网络协议基本功能与协议,TCP(Transmission Control Protocol)协议在传输层,IP(Internet Protocol)协议在网络层。
1.TCP协议:是一种面向连接的、可靠的、基于字节流的传输层通信协议,是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。互联网络与单个网络有很大的不同,因为互联网络的不同部分可能有截然不同的拓扑结构、带宽、延迟、数据包大小和其他参数。TCP的设计目标是能够动态地适应互联网络的这些特性,而且具备面对各种故障时的健壮性。
在这里插入图片描述
IP协议
2.IP协议:是网络之间信息传送的协议,可将IP信息包从源设备(例如用户的计算机)传送到目的设备(例如某部门的www服务器)。其目的一是解决互联网问题,实现大规模、异构网络的互联互通;二是分割顶层网络应用和底层网络技术之间的耦合关系,以利于两者的独立发展。
3.三次握手,四次分手
在这里插入图片描述
其中,SYN:同步序列编号(Synchronize Sequence Numbers),是TCP/IP建立连接时使用的握手信号。ACK:ACK (Acknowledge character)即是确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符。表示发来的数据已确认接收无误。
FIN_WAIT:FIN_WAIT_1和FIN_WAIT_2都是表示等待对方的FIN报文。
4. 套接字
应用层和传输层之间,是使用套接字来进行分离。套接字包含两个信息:连接至远程的本地的端口信息(本机地址和端口号),连接到的远程的端口信息(远程地址和端口号)。
5.TcpClient和TcpListener
.NET提供了这两个类将对套接字的编程进行了一个封装。
在这里插入图片描述
一般将发起连接的一方称为客户端,另一端称为服务端,则现在可以得出:总是服务端在使用TcpListener类,因为它需要建立起一个初始的连接。

IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });TcpListener listener = new TcpListener(ip, 8500);listener.Start();           // 开始侦听Console.WriteLine("Start Listening ...");

8500端口:提供获取服务列表、注册服务、注销服务等HTTP接口;提供UI服务,使用cmd:netstat -a;
每创建一个新的TcpClient便相当于创建了一个新的套接字Socket去与服务端通信,.Net会自动为这个套接字分配一个端口号.
创建TcpClient类型实例时,可以在构造函数中指定远程服务器的地址和端口号。这样在创建的同时,就会向远程服务端发送一个连接请求(“握手”),一旦成功,则两者间的连接就建立起来了。也可以使用重载的无参数构造函数创建对象,然后再调用Connect()方法,在Connect()方法中传入远程服务器地址和端口号,来与服务器建立连接,不管是使用有参数的构造函数与服务器连接,或者是通过Connect()方法与服务器建立连接,都是同步方法(或者说是阻塞的,英文叫block)。
6.端口通讯
在与服务端的连接建立以后,我们就可以通过此连接来发送和接收数据。端口与端口之间以流(Stream)的形式传输数据,因为几乎任何对象都可以保存到流中,所以实际上可以在客户端与服务端之间传输任何类型的数据。对客户端来说,往流中写入数据,即为向服务器传送数据;从流中读取数据,即为从服务端接收数据。对服务端来说,往流中写入数据,即为向客户端发送数据;从流中读取数据,即为从客户端接收数据。

二、示例

1.客户端和服务端建立连接

分别建立两个控制台程序。

class Client{static void Main(string[] args){TcpClient client = new TcpClient();try{client.Connect("local", 8500);  }catch (Exception ex){Console.WriteLine(ex.Message);return;}Console.WriteLine("Server Connected!{0} --> {1}",client.Client.LocalEndPoint, client.Client.RemoteEndPoint);}}
static void Main(string[] args){Console.WriteLine("Server is running ... ");IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });TcpListener listener = new TcpListener(ip, 8500);listener.Start();       Console.WriteLine("Start Listening ...");TcpClient remoteClient = listener.AcceptTcpClient();Console.WriteLine("Client Connected!{0} <-- {1}",remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);                }

结果就不显示了,反正都成功了,两个应用程序建立了连接。

2.一个客户端发出多个请求

static void Main(string[] args){const int BufferSize = 8192;    Console.WriteLine("Server is running ... ");IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });TcpListener listener = new TcpListener(ip, 8500);listener.Start(); Console.WriteLine("Start Listening ...");TcpClient remoteClient = listener.AcceptTcpClient();Console.WriteLine("Client Connected!{0} <-- {1}",remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);NetworkStream streamToClient = remoteClient.GetStream();do{byte[] buffer = new byte[BufferSize];int bytesRead = streamToClient.Read(buffer, 0, BufferSize);Console.WriteLine("Reading data, {0} bytes ...", bytesRead);string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);Console.WriteLine("Received: {0}", msg);} while (true);}
class Client{static void Main(string[] args){Console.WriteLine("Client Running ...");TcpClient client;try{client = new TcpClient();client.Connect("localhost", 8500);      catch (Exception ex){Console.WriteLine(ex.Message);return;}Console.WriteLine("Server Connected!{0} --> {1}",client.Client.LocalEndPoint, client.Client.RemoteEndPoint);NetworkStream streamToServer = client.GetStream();ConsoleKey key;Console.WriteLine("Menu: M - Send, G - Exit");do{key = Console.ReadKey(true).Key;if (key == ConsoleKey.M){Console.Write("Input the message: ");string msg = Console.ReadLine();byte[] buffer = Encoding.Unicode.GetBytes(msg);    streamToServer.Write(buffer, 0, buffer.Length);  Console.WriteLine("Sent: {0}", msg);}} while (key != ConsoleKey.G);//client.Close();}}

###3.服务端回传处理过的字符
服务端截取客户端传输的字符串,回传给客户端。

static void Main(string[] args){const int BufferSize = 8192;   ConsoleKey key;Console.WriteLine("Server is running ... ");IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });TcpListener listener = new TcpListener(ip, 8500);listener.Start();           Console.WriteLine("Start Listening ...");TcpClient remoteClient = listener.AcceptTcpClient();Console.WriteLine("Client Connected!{0} <-- {1}",remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);NetworkStream streamToClient = remoteClient.GetStream();do{byte[] buffer = new byte[BufferSize];int bytesRead;try{lock (streamToClient){bytesRead = streamToClient.Read(buffer, 0, BufferSize);}if (bytesRead == 0) throw new Exception("读取到0字节");Console.WriteLine("Reading data, {0} bytes ...", bytesRead);string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);Console.WriteLine("Received: {0}", msg);msg = msg.Substring(2);buffer = Encoding.Unicode.GetBytes(msg);lock (streamToClient){streamToClient.Write(buffer, 0, buffer.Length);}Console.WriteLine("Sent: {0}", msg);}catch (Exception ex){Console.WriteLine(ex.Message);break;}} while (true);streamToClient.Dispose();remoteClient.Close();Console.WriteLine("\n\n输入\"Q\"键退出。");do{key = Console.ReadKey(true).Key;} while (key != ConsoleKey.Q);}
class Client{static void Main(string[] args){Console.WriteLine("Client Running ...");TcpClient client;ConsoleKey key;const int BufferSize = 8192;try{client = new TcpClient();client.Connect("localhost", 8500);   }catch (Exception ex){Console.WriteLine(ex.Message);return;}Console.WriteLine("Server Connected!{0} --> {1}",client.Client.LocalEndPoint, client.Client.RemoteEndPoint);           NetworkStream streamToServer = client.GetStream();Console.WriteLine("Menu: S - Send, X - Exit");do{key = Console.ReadKey(true).Key;if (key == ConsoleKey.S){Console.Write("Input the message: ");string msg = Console.ReadLine();byte[] buffer = Encoding.Unicode.GetBytes(msg);   try{lock (streamToServer){streamToServer.Write(buffer, 0, buffer.Length);}Console.WriteLine("Sent: {0}", msg);int bytesRead;buffer = new byte[BufferSize];lock (streamToServer){bytesRead = streamToServer.Read(buffer, 0, BufferSize);}msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);Console.WriteLine("Received: {0}", msg);}catch (Exception ex){Console.WriteLine(ex.Message);break;}}} while (key != ConsoleKey.X);streamToServer.Dispose();client.Close();Console.WriteLine("\n\n输入\"Q\"键退出。");do{key = Console.ReadKey(true).Key;} while (key != ConsoleKey.Q);        }}

三、TCP端口状态说明

1.LISTENING状态

FTP (文件传输协议)服务器启动时后处于这一状态,直到和客户端连接成功。

2.ESTABLISHED状态

连接成功就处于这一状态,表示两端正在通讯。

3.CLOSE_WAIT状态

对方主动关闭连接或者网络异常导致连接中断均会变成此状态。

4.TIME_WAIT状态

主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态会一直持续2MSL(两倍的分段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。

5.SYN_SENT状态

SYN_SENT状态表示请求连接,当你要访问其它的计算机的服务时首先要发个同步信号给该端口,此时状态为SYN_SENT,如果连接成功了就变为 ESTABLISHED,此时SYN_SENT状态非常短暂。如果发现SYN_SENT非常多且在向不同的机器发出,机器可能中病毒了。

四、总结

总结下Socket:
1,建立服务端和客户端的连接。
2,客户端发送消息给服务端。
3,服务端接收到客户端的连接。
4,服务端对消息进行处理再发给客户端。
5. 客户端收到消息。
6. 结束。

参考文章:
以太网
七层网络协议–tcp/ip协议
网络编程

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

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

相关文章

WORD文档的超链接无法打开——“由于本机的限制该操作已被取消”的解决方法

之前我电脑还很正常&#xff0c;最近装了一个打印机后&#xff0c;放在word文档的文字超链接就打不开了&#xff0c;提示说“由于本机的限制该操作已被取消”&#xff0c;请各位高手指导下该怎样解决这个问题&#xff1f; WORD文档的超链接无法打开的原因是文件在插入超链接之…

配置https

引子&#xff1a; 最近在一篇文章中了解到EFF(电子前哨基金会)为了推广https协议&#xff0c;成立了一个letsencrypt项目&#xff0c;可以发放免费的证书&#xff0c;此证书可以被大多数主流浏览器所信任&#xff0c;这个邪恶的念头一爆发&#xff0c;就让我走上了一条坎坷的不…

CentOS 6.5安装VNC server

1. 安装桌面&#xff0c;安装时选择了Desktop可以忽略 # yum groupinstall Desktop # yum install gnome-core xfce4 firefox 2. 安装VNC server # yum install tigervnc-server 3. 配置服务 # chkconfig vncserver on 4. 设置VNC用户密码 # vncpasswd 5. 配置文件 # vi /etc/s…

C#中数据类型及其转换知识点汇总

概念 C#中数据类型分为两大类&#xff0c;分别是值类型和引用类型。 值类型变量是从类 System.ValueType 中派生出来的&#xff0c;当声明一个值类型变量时&#xff0c;系统分配内存来存储值。 整形 包括8种类型&#xff0c;区别在于字节数和有无符号。 浮点型 float占用…

10亿个字符串的排序问题

一、问题描述 有一个大文件&#xff0c;里面有十亿个字符串&#xff0c;乱序的&#xff0c;要求将这些字符串以字典的顺序排好序 二、解决思路 将大文件切割成小文件&#xff0c;每个小文件内归并排序&#xff1b; 对所有的小文件进行归并排序——多重归并排序 三、解决方案 3.…

史上超全halcon常见3D算子汇总(一)

读取3D模型 read_object_model_3d 此算子用于读取3D对象。 read_object_model_3d( : : FileName, Scale, GenParamName, GenParamValue : ObjectModel3D, Status) FileName:文件名,halcon支持多种3d数据格式的读取,包括 .off, .ply, .dxf, .om3, .obj, .stl等格式。 1).…

Python:常用模块简介(1)

sys模块 >>> sys.platform #返回操作系统平台名称 win32 >>> sys.stdin #输入相关 <open file <stdin>, mode r at 0x000000000337B030> >>> sys.stdout #输出相关 <open file <stdout>, mode w at 0x000000000337…

Windows10 VS2019下使用CMake3.20.1打开PCL1.11.0程序

安装CMake 为什么要使用cmake cmake 是kitware 公司以及一些开源开发者在开发几个工具套件(VTK)的过程中衍生品&#xff0c;成为一个独立的开放源代码项目。 CMake是一个很强大的编译配置工具&#xff0c;支持多种平台和编译器&#xff0c;通过编写CMakeLists.txt&#xff0c…

Java 并发---ConcurrentHashMap

concurrent包下的并发容器 JDK5中添加了新的concurrent包&#xff0c;相对同步容器而言&#xff0c;并发容器通过一些机制改进了并发性能。因为同步容器将所有对容器状态的访问都串行化了&#xff0c;这样保证了线程的安全性&#xff0c;所以这种方法的代价就是严重降低了并发性…

Windows10下安装QT5.14.2并用VS2019打开

安装 从官网下载&#xff1a;QT 安装方法仅需要注意&#xff1a; 1.最好不要安装在C盘。 2.根据开发需要安装功能模块&#xff0c;具体见参考文章。 https://jingyan.baidu.com/article/656db918d9292ae380249c4f.html 因为是用于PCL编程的&#xff0c;所以只选了msvc2017_64,…

C#中json序列化与反序列化

json格式概念 JSON(JavaScript Object Notation) 是一种轻量级的数据传输格式&#xff0c;其采用完全独立于语言的文本格式&#xff0c;使JSON成为理想的数据交换语言。 json由两种格式组成。 1.名称/值”对的集合&#xff0c;可以一起创建多个"名称 / 值对"。 { “…

volley用法之 以post方式发送 json 参数

需求是这样 我们需要发送一个post请求向服务器要参数。要求是发送的post参数也要是json格式。 简单一点的是这样的&#xff1a; 如果要发送的是这样简单的json格式&#xff0c;我们可以简单的使用map来实现&#xff1a; RequestQueue requestQueue Volley.newRequestQueue(get…

dns服务 很多问题,后续再研究

慕课网&#xff1a;http://www.imooc.com/video/5220 参考&#xff1a;http://jingyan.baidu.com/article/870c6fc32c028eb03fe4be30.html http://www.tuicool.com/articles/aUNzMfi http://www.07net01.com/linux/dnszhucongfuzhijiquyuchuansong_505144_1373161402.html http…

CDN架构以及原理分析

详见&#xff1a; http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp61 在不同地域的用户访问网站的响应速度存在差异,为了提高用户访问的响应速度、优化现有Internet中信息的流动,需要在用户和服务器间加入中间层CDN. 使用户能以最快的速度&#xff0c;从最接近用…

基于VS2019的Eigen库安装详解

概念 Eigen是一个C开源线性代数库&#xff0c;以提供有关矩阵的的线性代数运算&#xff0c;解方程等功能。Eigen在很多领域如信号处理&#xff0c;图像处理&#xff0c;深度学习等起到重要作用&#xff0c;学习其操作方法&#xff0c;可以灵活的对线性代数、矩阵和矢量将进行计…

SQL Server2012中如何通过bak文件还原SQL Server2012数据库

1 登陆完数据库后&#xff0c;不要新建数据库&#xff0c;直接点击“数据库”然后右击"还原数据库"。 2 在"源"选项中选择"设备"。 3 选择相应的bak文件并进行添加。 4 添加完之后点击确定&#xff0c;注意在目标这一栏中数据库名称都可以不用写…

thrift服务windows环境编译失败

为什么80%的码农都做不了架构师&#xff1f;>>> 修改maven的pom文件 <!--thrift服务 api 层&#xff0c;开发时 windows系统需指定exe程序位置--> <properties> <thrift.exe.path>E:/Thrift/thrift-0.9.3.exe</thrift.exe.path&g…

《第一行代码》学习笔记35-服务Service(2)

1.Android的UI线程不安全&#xff0c;想要更新应用程序里的UI元素&#xff0c;则须在主线程中进行&#xff0c;否则会出现异常。 2.Android不允许在子线程里进行UI操作&#xff0c;对于该情况&#xff0c;Android提供了一套异步消息处理机制&#xff0c;完美解决在子线程中进行…

基于C#的ico图标制作与应用

一、简介 ICO是什么 ICO 是 Windows 开发的一种图标格式&#xff0c;是一种可以存储多张图案、多尺寸、多色板的图标文件。 一般用IcoFX软件来创建或修改ico文件。 点击下载 Ico文件创建与应用 1.单击打开按钮&#xff0c;选择一个图像文件&#xff0c;确定后一般出现以下…

第5章--高级数据管理

5.1 数值和字符处理函数 常用的数学函数 统计函数 例子&#xff1a; > x <- c(1,2,3,4,5,6,7,8) > mean(x) [1] 4.5 > sd(x) [1] 2.44949 默认情况下&#xff0c;函数scale()对矩阵或数据框的指定列进行均值为0、标准差为1的标准化&#xff1a; newdata <- scal…