亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

淺談C#網絡編程詳解篇

2019-10-29 21:15:22
字體:
來源:轉載
供稿:網友

閱讀目錄:

基礎
Socket編程
多線程并發
阻塞式同步IO

基礎
在現今軟件開發中,網絡編程是非常重要的一部分,本文簡要介紹下網絡編程的概念和實踐。
Socket是一種網絡編程接口,它是對傳輸層TCP、UDP通信協議的一層封裝,通過友好的API暴露出去,方便在進程或多臺機器間進行網絡通信。

C#,網絡編程

 

Socket編程

在網絡編程中分客戶端和服務端兩種角色,比如通過打開瀏覽器訪問到掛在Web軟件上的網頁,從程序角度上來看,即客戶端(瀏覽器)發起了一個Socket請求到服務器端,服務器把網頁內容返回到瀏覽器解析后展示。在客戶端和服務端數據通信前,會進行三次確認才會正式建立連接,也即是三次握手。

  1. 客戶端發送消息詢問服務端是否準備好
  2. 服務端回應我準備好了,你呢準備好了嗎
  3. 客戶端回應服務端我也準備好了,可以通信了

TCP/IP協議是網絡間通信的基礎協議,在不同編程語言及不同操作系統下暴露的Socket接口用法也大同小異,僅是其內部實現有所不同,比如Linux下的epoll和windows下的IOCP。

服務端
  • 實例化Socket
  • 把公共地址端口綁定操作系統上
  • 開始監聽綁定的端口
  • 等待客戶端連接
IPEndPoint ip = new IPEndPoint(IPAddress.Any, 6389);      Socket listenSocket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);      listenSocket.Bind(ip);      listenSocket.Listen(100);      listenSocket.Accept();

listen函數中有個int類型參數,它表示最大等待處理連接的數量,表示已建立連接但還未處理的數量,每調用Accept函數一下即從這個等待隊列中拿出一個連接。 通常服務端要服務多個客戶端請求的連接,所以會循環從等待隊列中拿出連接,進行接收發送。

while (true)       {         var accept= listenSocket.Accept();        accept.Receive();         accept.Send();       }

C#,網絡編程

多線程并發
上面的服務端程序處理接收和發送消息都是在當前線程下完成的,這意味著要處理完一個客戶端連接后才能去處理下一個連接,如果當前連接是進行數據庫或者文件讀取寫入等IO操作,那會極大浪費服務器的CPU資源,降低了服務器吞吐量。

while (true)      {        var accept = listenSocket.Accept();        ThreadPool.QueueUserWorkItem((obj) =>        {          byte[] receive = new byte[100];          accept.Receive(receive);          byte[] send = new byte[100];          accept.Send(receive);        });      }

如例子中,當監聽到有新連接請求過來時,調用Accept()取出當前連接的socket,使用新的線程去處理接收和發送信息,這樣服務端就能實現并發處理多個客戶端了。 上述代碼中,在高并發下其實是有問題的,如果客戶端連接請求成千上萬個,那線程數量也會有這么多,每個線程的??臻g都需要消耗部分內存,再加上線程上下文切換,容易導致服務器負載過高,吞吐量大大下降,嚴重時會引起宕機。 當前例子中使用系統ThreadPool的話,線程數量會固定在一個數量上,默認是1000,不會無限制開線程,會把處理超出線程數量的請求放到線程池中的隊列上面。
在unix下類似的實現有2種:

fork一個新進程去處理客戶端的連接:

var connfd = Accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len); var m = fork(); if(m == 0) { //do something }

創建一個新的線程處理限流:

var *clientsockfd = accept(serversockfd,(struct sockaddr *)&clientaddress, (socklent *)&clientlen); if(pthreadcreate(&thread, NULL, recdata, clientsockfd)!=0) { //do something }

阻塞式同步IO
上述例子中使用的即是該模型,使用起來簡單方便。

while (true)      {        var accept = listenSocket.Accept();        byte[] receive = new byte[100];        accept.Receive(receive);        byte[] send = new byte[100];        accept.Send(receive);      }

從調用Receive函數起到接受到客戶端發過來的數據期間,該函數會一直阻塞等待著,這個阻塞期間處理流程如下:

  1. 客戶端發送數據
  2. 通過廣域網局域網發送到服務端機器網卡緩沖區上
  3. 網卡驅動對CPU發送中斷指令
  4. CPU把數據拷貝到內核緩沖區
  5. CPU再把內核緩沖區的數據拷貝用戶緩沖區,上面的receive字節數組。

至此處理成功,開始處理下一個連接請求。 調用發送函數同樣會阻塞在當前,然后把用戶緩沖區(send字節數組)數據拷貝到內核中TCP發送緩沖區中。 TCP的發送緩沖區也有一定的大小限制,如果發送的數據大于該限制,send函數會一直等待發送緩沖區有空閑時完全拷貝完才會返回,繼續處理后續連接請求。

異步IO
上篇提到用多線程處理多個阻塞同步IO而實現并發服務端,這種模式在連接數量比較小的時候非常適合,一旦連接過多,性能會急速下降。 在大多數服務端網絡軟件中會采用一種異步IO的方式來提高性能。

同步IO方式:連接Receive請求->等待->等待->接收成功
異步IO方式:連接Receive請求->立即返回->事件或回調通知
采用異步IO方式,意味著單線程可以處理多個請求了,連接發起一個Receive請求后,當前線程可以立即去做別的事情,當數據接收完畢通知線程處理即可。
其數據接收分2部分:

數據從別的機器發送內核緩沖區
內核緩沖區拷貝到用戶緩沖區
第二部分示例代碼:

byte[] msg = new byte[256]; socket.Receive(msg);

介紹這2部分的目的是方便區分其他幾種方式。 對于用戶程序來說,同步IO和異步IO的區別在于第二部分是否需要等待。

非阻塞式同步IO
非阻塞式同步IO,由同步IO延伸出來,把這個名詞拆分成2部分描述:

  • 非阻塞式,指的是上節"數據從別的機器發送內核緩沖區"部分是非阻塞的。
  • 同步IO,指的是上節"內核緩沖區拷貝到用戶緩沖區"部分是等待的。

既然是第一部分是非阻塞的,那就需要一種方法得知什么時候內核緩沖區是OK的。 設置非阻塞模式后,在連接調用Receive方法時,會立即返回一個標記,告知用戶程序內核緩存區有沒有數據,如果有數據開始進行第二部分操作,從內核緩沖區拷貝到用戶程序緩沖區。 由于系統會返回個標記,那可以通過輪詢方式來判斷內核緩沖區是否OK。

設置非阻塞模式參考代碼:

SocketInformation sif=new SocketInformation();sif.Options=SocketInformationOptions.NonBlocking;sif.ProtocolInformation = new byte[24];Socket socket = new Socket(sif);

輪詢參考代碼:

while(true) {byte[] msg = new byte[256];var temp = socket.Receive(msg);if (temp=="OK"){//do something}else{ continue }}

這種方式近乎淘汰了,了解即可。

基于回調的異步IO
上面介紹過:

異步IO方式:連接Receive請求->立即返回->事件或回調通知
當回調到執行時,數據已經在用戶程序緩沖區已經準備好了,在回調代碼中對這部分數據進行相應的邏輯即可。

發出接收請求:

static byte[] msg = new byte[256]; var temp = socket.BeginReceive(msg, 0, msg.Length, 0, new AsyncCallback(ReadCallback), socket);

回調函數中對數據做處理:

public static void ReadCallback(IAsyncResult ar) { var socket = (Socket)ar.AsyncState; int read = socket.EndReceive(ar);DoSomething(msg); socket.BeginReceive(msg, 0, msg.Length, 0, new AsyncCallback(Read_Callback), socket);}

當回調函數執行時,表示數據已經準備好,需要先結束接收請求EndReceive,以便第二次發出接收請求。 在服務端程序中要處理多個客戶端的接收,再次發出BeginReceive接收數據請求即可。

這里的回調函數是在另外一個線程的觸發,必要時要對數據加鎖防止數據競爭:

Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

針對C#網絡編程的介紹就到這了,具體的大家可以查看VEVB武林網之前發布的文章。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产日产欧美精品| 久久偷看各类女兵18女厕嘘嘘| 国产精品久久久久久久美男| 亚洲wwwav| 国产精品久久久久久久久久久不卡| 欧美体内谢she精2性欧美| 最近2019年好看中文字幕视频| 日av在线播放中文不卡| 911国产网站尤物在线观看| 欧美老少做受xxxx高潮| 91亚洲精品久久久久久久久久久久| 欧美成人网在线| 久久久久中文字幕| 国产一区二区三区中文| 亚洲人永久免费| 91视频九色网站| 国产精品入口日韩视频大尺度| 国产成人精品在线视频| 亚洲国产精品999| 亚洲网站在线播放| 亚洲乱码一区二区| 亚洲加勒比久久88色综合| 日韩精品极品在线观看播放免费视频| 国产一区玩具在线观看| 中文字幕av一区| 久久精品在线视频| 国产精品福利在线| 中文字幕欧美精品日韩中文字幕| 裸体女人亚洲精品一区| 精品免费在线视频| 日韩精品中文字幕在线观看| 亚洲午夜未删减在线观看| 热久久视久久精品18亚洲精品| 国产精品日韩一区| 欧美激情视频网站| 这里精品视频免费| 久久精视频免费在线久久完整在线看| 国产999在线观看| 久久久成人精品视频| 大胆欧美人体视频| 日韩精品在线免费观看视频| 欧美日韩国产一区在线| 国产午夜精品全部视频播放| 青青草成人在线| 68精品久久久久久欧美| 成人黄色片网站| 国产激情久久久| 精品一区二区三区四区| 91在线观看免费观看| 久久精视频免费在线久久完整在线看| 青草青草久热精品视频在线观看| 亚洲女性裸体视频| 欧洲成人免费aa| 欧美高清视频免费观看| 亚洲偷欧美偷国内偷| 亚洲美女www午夜| 欧美有码在线视频| 日韩激情第一页| 亚洲r级在线观看| 欧美华人在线视频| 欧美性xxxxx极品娇小| 性色av香蕉一区二区| 韩国美女主播一区| 国产一区二区三区在线免费观看| 久久久久一本一区二区青青蜜月| 欧美成人h版在线观看| 91av在线免费观看视频| 国产精品久久久久久久久免费看| 91精品国产91久久久久久不卡| 九九久久精品一区| 97视频在线观看亚洲| 国产精品九九久久久久久久| 国产91av在线| 国产精品香蕉国产| 国产精品99久久久久久人| 国产丝袜精品视频| 久久av.com| 国产亚洲xxx| 国产精品美女无圣光视频| 国产精品视频中文字幕91| 日韩精品视频在线| 久久久久久中文字幕| 国产亚洲免费的视频看| 亚洲欧美日韩精品久久亚洲区| 日韩高清不卡av| 国产精品久久电影观看| 国产精品普通话| 欧美乱大交xxxxx另类电影| 国产精品久久久久久久app| 精品国产欧美成人夜夜嗨| 欧美日韩国产中文字幕| 96国产粉嫩美女| 亚洲品质视频自拍网| 久久精品国产一区二区三区| 狠狠操狠狠色综合网| 亚洲国产精品电影在线观看| 亚洲福利视频网| 成人精品久久av网站| 成人性教育视频在线观看| 欧美激情欧美激情在线五月| 在线看福利67194| 中文字幕欧美亚洲| 亚洲人成网在线播放| 国外成人性视频| 成人a视频在线观看| 欧美成人免费在线观看| 国产精品99久久99久久久二8| 亚洲国产天堂久久综合网| 久久偷看各类女兵18女厕嘘嘘| 久久久久久久久久久人体| 亚洲国产毛片完整版| 久久在线视频在线| 国产精品一区二区三区免费视频| 在线成人免费网站| 久久伊人精品天天| 国内精品小视频在线观看| 亚洲欧美日韩中文在线| 精品国产欧美成人夜夜嗨| 亚洲欧美另类在线观看| 韩剧1988在线观看免费完整版| 国产不卡精品视男人的天堂| 精品av在线播放| 国产日韩欧美电影在线观看| 久久香蕉国产线看观看av| 国模吧一区二区三区| 欧美国产在线视频| 2021国产精品视频| 7m第一福利500精品视频| 亚洲图片欧美午夜| 91地址最新发布| 亚洲一区亚洲二区亚洲三区| 日韩精品视频在线免费观看| 久久91亚洲精品中文字幕奶水| 亚洲网站在线观看| 亚洲跨种族黑人xxx| 中文字幕久久久av一区| 久久伊人精品一区二区三区| 日韩av电影手机在线| 在线观看国产欧美| 91国语精品自产拍在线观看性色| 久久精品视频网站| 日韩有码在线观看| 国产成人涩涩涩视频在线观看| 日韩欧美一区二区在线| 久久亚洲国产精品| 成人97在线观看视频| 亚洲国产精品久久| 中文字幕精品一区二区精品| 色悠悠国产精品| 国产精品免费网站| 在线观看中文字幕亚洲| 亚洲色图欧美制服丝袜另类第一页| 92看片淫黄大片欧美看国产片| 性欧美在线看片a免费观看| 国产成人精品电影| 日本精品久久电影| 精品中文视频在线| 久久久久久久爱| 精品成人乱色一区二区| 国产精品福利在线| 日韩av三级在线观看| 国产精品一区二区性色av| 久久久国产一区二区三区| 国产激情999|