基于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.pswp.cn/news/256302.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/256302.shtml
英文地址,請注明出處:http://en.pswp.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…