日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

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

發(fā)布時(shí)間:2023/12/10 C# 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于C#的TCP/IP协议应用(一) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、背景與概念

1.標(biāo)準(zhǔn)以太網(wǎng)

以太網(wǎng)是美國Xerox(施樂)公司的Palo Alto研究中心于1975年研制成功的,其核心技術(shù)起源于ALOHA網(wǎng)。目前以太網(wǎng)是指符合IEEE 802.3標(biāo)準(zhǔn)的局域網(wǎng)(LAN)產(chǎn)品組,其中IEEE 802.3是一組電氣與電子工程師協(xié)會(huì)(IEEE)標(biāo)準(zhǔn),用于定義有線以太網(wǎng)媒體訪問控制的物理層和數(shù)據(jù)鏈路層,說明了配置以太網(wǎng)網(wǎng)絡(luò)的規(guī)則,以及各種網(wǎng)絡(luò)元件如何彼此協(xié)作。以太網(wǎng)分為:
1.標(biāo)準(zhǔn)以太網(wǎng):早期的10Mbps以太網(wǎng)稱之為標(biāo)準(zhǔn)以太網(wǎng),是一種總線型局域網(wǎng),由同軸電纜、網(wǎng)卡(網(wǎng)絡(luò)適配器)組成。。

發(fā)送和接收數(shù)據(jù)通過CSMA/CD協(xié)議完成,流程可以簡單概括為四點(diǎn):先聽后發(fā),邊聽邊發(fā),沖突停止,延遲重發(fā)
2.總線以太網(wǎng)通過中繼器、網(wǎng)橋進(jìn)行擴(kuò)展。
中繼器(Repeater)也叫轉(zhuǎn)發(fā)器,將在傳輸介質(zhì)中衰減的信號(hào)放大,以增加線纜的傳輸距離。
網(wǎng)橋(Bridge)又稱橋接器,是一種存儲(chǔ)轉(zhuǎn)發(fā)設(shè)備。它工作在數(shù)據(jù)鏈路層,當(dāng)它收到一個(gè)幀時(shí),先檢查此幀的目的MAC地址,然后再確定將該幀轉(zhuǎn)發(fā)到哪一個(gè)端口。
以太網(wǎng)種類繁多,包括基于集線器的以太網(wǎng),基于交換機(jī)的以太網(wǎng)等,目前已發(fā)展到十萬兆以太網(wǎng)。。

2.工業(yè)以太網(wǎng)

工業(yè)以太網(wǎng)一般來講是指技術(shù)上與商用以太網(wǎng)(即IEEE802.3標(biāo)準(zhǔn))兼容,但在產(chǎn)品設(shè)計(jì)時(shí),在材質(zhì)的選用、產(chǎn)品的強(qiáng)度、適用性以及實(shí)時(shí)性等方面能滿足工業(yè)現(xiàn)場的需要。
目前包括4種主要協(xié)議:HSE、Modbus TCP/IP、ProfINet、Ethernet/IP。
基金會(huì)現(xiàn)場總線FF于2000年發(fā)布Ethernet規(guī)范,稱HSE(High Speed Ethernet)。
Modbus TCP/IP協(xié)議由施耐德公司推出,以一種非常簡單的方式將Modbus幀嵌入到TCP幀中,使Modbus與以太網(wǎng)和TCP/IP結(jié)合。
德國西門子于2001年發(fā)布了ProfiNet網(wǎng)絡(luò)方案,它是將原有的Profibus與互聯(lián)網(wǎng)技術(shù)結(jié)合。ProfiNet采用標(biāo)準(zhǔn)TCP/IP協(xié)議加上應(yīng)用層的RPC/DCOM來完成節(jié)點(diǎn)間的通信和網(wǎng)絡(luò)尋址。
Ethernet/IP是適合工業(yè)環(huán)境應(yīng)用的協(xié)議體系,基于CIP(Controland Information Proto-Col)協(xié)議。它是一種是面向?qū)ο蟮膮f(xié)議,能夠保證網(wǎng)絡(luò)上隱式(控制)的實(shí)時(shí)I/O信息和顯式信息(包括用于組態(tài)、參數(shù)設(shè)置、診斷等) 的有效傳輸。
工業(yè)以太網(wǎng)設(shè)備包括以下幾個(gè)重要部分:
1.工業(yè)以太網(wǎng)集線器
2.工業(yè)以太網(wǎng)非管理型交換機(jī)
3.工業(yè)以太網(wǎng)管理型交換機(jī)
4.工業(yè)以太網(wǎng)管理型冗余交換機(jī)

3.TCP/IP協(xié)議


上表為網(wǎng)絡(luò)協(xié)議基本功能與協(xié)議,TCP(Transmission Control Protocol)協(xié)議在傳輸層,IP(Internet Protocol)協(xié)議在網(wǎng)絡(luò)層。
1.TCP協(xié)議:是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,是為了在不可靠的互聯(lián)網(wǎng)絡(luò)上提供可靠的端到端字節(jié)流而專門設(shè)計(jì)的一個(gè)傳輸協(xié)議。互聯(lián)網(wǎng)絡(luò)與單個(gè)網(wǎng)絡(luò)有很大的不同,因?yàn)榛ヂ?lián)網(wǎng)絡(luò)的不同部分可能有截然不同的拓?fù)浣Y(jié)構(gòu)、帶寬、延遲、數(shù)據(jù)包大小和其他參數(shù)。TCP的設(shè)計(jì)目標(biāo)是能夠動(dòng)態(tài)地適應(yīng)互聯(lián)網(wǎng)絡(luò)的這些特性,而且具備面對各種故障時(shí)的健壯性。


2.IP協(xié)議:是網(wǎng)絡(luò)之間信息傳送的協(xié)議,可將IP信息包從源設(shè)備(例如用戶的計(jì)算機(jī))傳送到目的設(shè)備(例如某部門的www服務(wù)器)。其目的一是解決互聯(lián)網(wǎng)問題,實(shí)現(xiàn)大規(guī)模、異構(gòu)網(wǎng)絡(luò)的互聯(lián)互通;二是分割頂層網(wǎng)絡(luò)應(yīng)用和底層網(wǎng)絡(luò)技術(shù)之間的耦合關(guān)系,以利于兩者的獨(dú)立發(fā)展。
3.三次握手,四次分手

其中,SYN:同步序列編號(hào)(Synchronize Sequence Numbers),是TCP/IP建立連接時(shí)使用的握手信號(hào)。ACK:ACK (Acknowledge character)即是確認(rèn)字符,在數(shù)據(jù)通信中,接收站發(fā)給發(fā)送站的一種傳輸類控制字符。表示發(fā)來的數(shù)據(jù)已確認(rèn)接收無誤。
FIN_WAIT:FIN_WAIT_1和FIN_WAIT_2都是表示等待對方的FIN報(bào)文。
4. 套接字
應(yīng)用層和傳輸層之間,是使用套接字來進(jìn)行分離。套接字包含兩個(gè)信息:連接至遠(yuǎn)程的本地的端口信息(本機(jī)地址和端口號(hào)),連接到的遠(yuǎn)程的端口信息(遠(yuǎn)程地址和端口號(hào))。
5.TcpClient和TcpListener
.NET提供了這兩個(gè)類將對套接字的編程進(jìn)行了一個(gè)封裝。

一般將發(fā)起連接的一方稱為客戶端,另一端稱為服務(wù)端,則現(xiàn)在可以得出:總是服務(wù)端在使用TcpListener類,因?yàn)樗枰⑵鹨粋€(gè)初始的連接。

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

8500端口:提供獲取服務(wù)列表、注冊服務(wù)、注銷服務(wù)等HTTP接口;提供UI服務(wù),使用cmd:netstat -a;
每創(chuàng)建一個(gè)新的TcpClient便相當(dāng)于創(chuàng)建了一個(gè)新的套接字Socket去與服務(wù)端通信,.Net會(huì)自動(dòng)為這個(gè)套接字分配一個(gè)端口號(hào).
創(chuàng)建TcpClient類型實(shí)例時(shí),可以在構(gòu)造函數(shù)中指定遠(yuǎn)程服務(wù)器的地址和端口號(hào)。這樣在創(chuàng)建的同時(shí),就會(huì)向遠(yuǎn)程服務(wù)端發(fā)送一個(gè)連接請求(“握手”),一旦成功,則兩者間的連接就建立起來了。也可以使用重載的無參數(shù)構(gòu)造函數(shù)創(chuàng)建對象,然后再調(diào)用Connect()方法,在Connect()方法中傳入遠(yuǎn)程服務(wù)器地址和端口號(hào),來與服務(wù)器建立連接,不管是使用有參數(shù)的構(gòu)造函數(shù)與服務(wù)器連接,或者是通過Connect()方法與服務(wù)器建立連接,都是同步方法(或者說是阻塞的,英文叫block)。
6.端口通訊
在與服務(wù)端的連接建立以后,我們就可以通過此連接來發(fā)送和接收數(shù)據(jù)。端口與端口之間以流(Stream)的形式傳輸數(shù)據(jù),因?yàn)閹缀跞魏螌ο蠖伎梢员4娴搅髦?#xff0c;所以實(shí)際上可以在客戶端與服務(wù)端之間傳輸任何類型的數(shù)據(jù)。對客戶端來說,往流中寫入數(shù)據(jù),即為向服務(wù)器傳送數(shù)據(jù);從流中讀取數(shù)據(jù),即為從服務(wù)端接收數(shù)據(jù)。對服務(wù)端來說,往流中寫入數(shù)據(jù),即為向客戶端發(fā)送數(shù)據(jù);從流中讀取數(shù)據(jù),即為從客戶端接收數(shù)據(jù)。

二、示例

1.客戶端和服務(wù)端建立連接

分別建立兩個(gè)控制臺(tái)程序。

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); }

結(jié)果就不顯示了,反正都成功了,兩個(gè)應(yīng)用程序建立了連接。

2.一個(gè)客戶端發(fā)出多個(gè)請求

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.服務(wù)端回傳處理過的字符
服務(wù)端截取客戶端傳輸?shù)淖址?#xff0c;回傳給客戶端。

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字節(jié)");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端口狀態(tài)說明

1.LISTENING狀態(tài)

FTP (文件傳輸協(xié)議)服務(wù)器啟動(dòng)時(shí)后處于這一狀態(tài),直到和客戶端連接成功。

2.ESTABLISHED狀態(tài)

連接成功就處于這一狀態(tài),表示兩端正在通訊。

3.CLOSE_WAIT狀態(tài)

對方主動(dòng)關(guān)閉連接或者網(wǎng)絡(luò)異常導(dǎo)致連接中斷均會(huì)變成此狀態(tài)。

4.TIME_WAIT狀態(tài)

主動(dòng)調(diào)用close()斷開連接,收到對方確認(rèn)后狀態(tài)變?yōu)門IME_WAIT。TCP協(xié)議規(guī)定TIME_WAIT狀態(tài)會(huì)一直持續(xù)2MSL(兩倍的分段最大生存期),以此來確保舊的連接狀態(tài)不會(huì)對新連接產(chǎn)生影響。

5.SYN_SENT狀態(tài)

SYN_SENT狀態(tài)表示請求連接,當(dāng)你要訪問其它的計(jì)算機(jī)的服務(wù)時(shí)首先要發(fā)個(gè)同步信號(hào)給該端口,此時(shí)狀態(tài)為SYN_SENT,如果連接成功了就變?yōu)?ESTABLISHED,此時(shí)SYN_SENT狀態(tài)非常短暫。如果發(fā)現(xiàn)SYN_SENT非常多且在向不同的機(jī)器發(fā)出,機(jī)器可能中病毒了。

四、總結(jié)

總結(jié)下Socket:
1,建立服務(wù)端和客戶端的連接。
2,客戶端發(fā)送消息給服務(wù)端。
3,服務(wù)端接收到客戶端的連接。
4,服務(wù)端對消息進(jìn)行處理再發(fā)給客戶端。
5. 客戶端收到消息。
6. 結(jié)束。

參考文章:
以太網(wǎng)
七層網(wǎng)絡(luò)協(xié)議–tcp/ip協(xié)議
網(wǎng)絡(luò)編程

總結(jié)

以上是生活随笔為你收集整理的基于C#的TCP/IP协议应用(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。