基于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文档的超链接无法打开的原因是文件在插入超链接之…

广义表的实现

广义表是一种非线性表的数据结构&#xff0c;是线性表的一种推广。他放松了对原子的控制&#xff0c;容许原子有自身的结构。其实现如下&#xff1a; #include<iostream>using namespace std;#include<assert.h>enum Type //原子类型有三种:头结点&#xff0c…

C#中List列表与Datagridview的用法

初始化 创建空列表 List<int> List new List<int>();2.使用var类型的前提是预先知道变量的类型&#xff0c;会根据变量赋值来判定属于什么类型&#xff0c;但此种赋值方法只能给局部变量赋值。 var list1 new List<string>();具体见&#xff1a; C#列表L…

Byte和byte[]数组

Byte和byte[]数组&#xff0c;“表示一个 8 位无符号整数, 一般为8位二进制数”。 Byte是计算机最基础的存储单位和最基础的通讯单位。 而所有的类型都是支持由byte[]类型转换而来。 为什么说Byte是最基础类型那&#xff0c; 其实这里的关键所在是&#xff0c;计算机最基础的算…

【图像处理】——opencv常用函数

目录 读取图像 注意: 1、imread和plt.show以及pil.image,show的区别: 2、imread中的rgb的顺序 显示图像

网络协议:TCP/IP、SOCKET、HTTP

网络七层 由下往上分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。其中物理层、数据链路层和网络层通常被称作媒体层&#xff0c;是网络工程师所研究的对象&#xff1b;传输层、会话层、表示层和应用层则被称作主机层&#xff0c;是用户所面向和关心的内…

halcon自标定

概念 该算法可以在不使用标定板的情况下计算相机内参&#xff0c;从而进行畸变校正&#xff0c;适用于畸变较大的情况。算法很简单&#xff1a; 1.求出图像边缘应进行分割。 2.基于筛选线段的自标定radial_distortion_self_calibration。 3.得到标定区域。 4.根据指定的径向畸…

jdk动态代理

简单的说&#xff0c;代理模式是在目标对象和访问对象之间增加了一层代理对象&#xff0c;所有的访问对象通过代理对象来实现对目标对象的调用。 代理对象和目标对象实现同一个接口&#xff0c;由代理对象来调用目标对象&#xff0c;对于外部来说&#xff0c;代理对象就可以替代…

【图像处理】——图像的灰度化处理(Python实现三种方法——最大值法、平均值法、加权均值法、gamma校正)

目录 一、什么是图像的灰度化? 二、灰度化的几种方法(最大值法、平均值法、加权均值法、gamma校正)

配置https

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

C# —— 序列化与反序列化

概念 序列化 通过使用不同的类(BinaryFormatter,SoapFormatter,XmlSerializer)将对象状态转换为可保持或传输的格式的过程,具体是将对象转变为字节流,其目的是为了保存数据的状态,方便后续还原调用。包括三种序列化形式:二进制序列化,SOAP序列化,XML序列化。于此过…

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…

【图像处理】——图像灰度直方图的绘制(直接调用函数和自定义函数)

目录 一、灰度直方图概念 二、直接调用opencv的函数caclHist() 1、函数介绍 2、实例 <

Codeforces 722C. Destroying Array

C. Destroying Arraytime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputYou are given an array consisting of n non-negative integers a1, a2, ..., an. You are going to destroy integers in the array one by o…

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

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

10亿个字符串的排序问题

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

MVC学习IIS的不同版本(一)

一&#xff1a;IIS5.0运行在进程InetInfo.exe中&#xff0c;该进程寄宿着一个名为World Wide Publishing Service&#xff08;W3VC&#xff09;的window服务。 W3VC的主要功能&#xff1a;包括HTTP请求的监听、工作进程和配置管理 检测到HTTP 请求时&#xff1a; 根据扩展名判断…

Halcon中visualize_object_model_3d算子详解

概念 此函数用于显示3d模型。该函数功能很多,包括设置位姿,颜色,鼠标翻转、缩放、平移,选择和取消选择目标,降低鼠标灵敏度,切换检查模式等。 参数 visualize_object_model_3d( : : WindowHandle, ObjectModel3D, CamParam, PoseIn, GenParamName, GenParamValue, Tit…

random()模块随机函数的用法总结

random()是Python中生成随机数的函数&#xff0c;是由random模块控制&#xff0c;random()函数不能直接访问&#xff0c;需要导入random 模块&#xff0c;然后再通过相应的静态对象调用该方法才能实现相应的功能 目录 1. random.random() 2. random.uniform() 3. random.ra…