許銳炮
(民航汕頭空管站 技術(shù)保障部,廣東 揭東515558)
當(dāng)前網(wǎng)絡(luò)通信日益應(yīng)用廣泛,以民航汕頭空管站為例,單業(yè)務(wù)網(wǎng)就超過(guò)5 個(gè),而信息化集中程度越來(lái)越多的同時(shí),分布式系統(tǒng)之間的信息傳輸也成為一個(gè)研究課題。 而對(duì)于傳統(tǒng)的TCP/IP 協(xié)議來(lái)說(shuō),TCP能提供一種可靠的、有連接的數(shù)據(jù)流服務(wù),IP 協(xié)議則能通過(guò)識(shí)別IP 地址實(shí)現(xiàn)網(wǎng)絡(luò)個(gè)體的互相通信, 相關(guān)文獻(xiàn)也將兩者稱為底層網(wǎng)絡(luò)通信。而對(duì)比之下,已經(jīng)成熟應(yīng)用的Socket 中間件便可以以應(yīng)用程序的方式存在于各大網(wǎng)絡(luò)分布式系統(tǒng),應(yīng)用日趨廣泛。因此,探討Socket 的運(yùn)行機(jī)制及應(yīng)用對(duì)相關(guān)網(wǎng)絡(luò)編程和技術(shù)維護(hù)有一定意義。本文將從實(shí)際出發(fā),介紹其在C# 程序編寫(xiě)中的相關(guān)技術(shù)及特點(diǎn)。
Socket 是應(yīng)用層與TCP/IP 協(xié)議族通信的中間軟件抽象層,它是一組接口。 在設(shè)計(jì)模式中,Socket 作為一個(gè)門(mén)面模式把復(fù)雜的TCP/IP 協(xié)議族隱藏在Socket 接口后面,對(duì)開(kāi)發(fā)人員來(lái)說(shuō),一組簡(jiǎn)單的接口就是全部,讓Socket 去組織數(shù)據(jù),以符合指定的協(xié)議。 它主要由IP 地址和端口號(hào)組成。 在TCP/IP 網(wǎng)絡(luò)協(xié)議中, 基于服務(wù)器客戶端模式的通信上,建立Socket 連接至少需要一對(duì)套接字,其中一個(gè)運(yùn)行于客戶端,稱為ClientSocket , 另一個(gè)運(yùn)行于服務(wù)器端, 稱為ServerSocket 。 對(duì)于ServerSocket 來(lái)說(shuō)主要用于服務(wù)器監(jiān)聽(tīng), 服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài),等待客戶端的連接請(qǐng)求。一旦有請(qǐng)求或者相關(guān)命令信息,立即響應(yīng)。而對(duì)于ClientSocket 來(lái)說(shuō)將主動(dòng)向服務(wù)器端套接字發(fā)出連接請(qǐng)求。因此,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號(hào), 然后就向服務(wù)器端套接字提出連接請(qǐng)求。當(dāng)服務(wù)器端套接字監(jiān)聽(tīng)到或者說(shuō)接收到客戶端套接字的連接請(qǐng)求時(shí),就響應(yīng)客戶端套接字的請(qǐng)求,建立一個(gè)新的線程,把服務(wù)器端套接字的描述發(fā)給客戶端,一旦客戶端確認(rèn)了此描述,雙方就正式建立連接。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽(tīng)狀態(tài),繼續(xù)接收其他客戶端套接字的連接請(qǐng)求。
C# Socket 類為網(wǎng)絡(luò)通信提供了一套豐富的方法和屬性。 Socket類允許開(kāi)發(fā)人員使用ProtocolType 枚舉中所列出的任何一種協(xié)議執(zhí)行異步和同步數(shù)據(jù)傳輸。 如果應(yīng)用程序在執(zhí)行期間只需要一個(gè)線程。對(duì)于面向連接的協(xié)議的TCP 協(xié)議通信, 服務(wù)器可以使用Listen 方法偵聽(tīng)連接。 Accept 方法則處理任何傳入的連接請(qǐng)求,并返回可用于與遠(yuǎn)程主機(jī)進(jìn)行數(shù)據(jù)通信的Socket。 同時(shí)可以使用此返回的Socket 來(lái)調(diào)用Send 或Receive 方法。 調(diào)用Bind 方法后便可以要指定本地IP地址和端口號(hào)。連接偵聽(tīng)主機(jī),則可以調(diào)用Connect 方法。在數(shù)據(jù)通信上,主要用Send 或Receive 方法。
對(duì) 于TCP/IP 的 通 信 在C# 中 可 使 用 Socket、BeginConnect 和EndConnect 方法來(lái)連接偵聽(tīng)主機(jī)。 通過(guò)使用BeginSend 和EndSend方法,或者使用BeginReceive 和EndReceive 方法,可以進(jìn)行異步數(shù)據(jù)通信。 與此同時(shí),使用BeginAccept 和EndAccept 處理傳入的連接請(qǐng)求。
而在實(shí)際應(yīng)用中,C# 的Socket 經(jīng)常需要與多線程配合以解決異步傳輸問(wèn)題。C# 支持通過(guò)多線程并行地執(zhí)行代碼,一個(gè)線程有它獨(dú)立的執(zhí)行路徑,能夠與其它的線程同時(shí)地運(yùn)行。一個(gè)C# 程序開(kāi)始于一個(gè)單線程,這個(gè)單線程是被CLR 和操作系統(tǒng)(也稱為“主線程”)自動(dòng)創(chuàng)建的,并具有多線程創(chuàng)建額外的線程。
作為典型的C/S 模式結(jié)構(gòu)設(shè)計(jì),一般情況下包括服務(wù)器端軟件設(shè)計(jì)和客戶端軟件設(shè)計(jì),因此服務(wù)器端軟件與客戶端軟件不可避免需要對(duì)其進(jìn)行網(wǎng)絡(luò)通信編程。以客戶端軟件設(shè)計(jì)為例,Socket 在C# 中則可以通過(guò)以下實(shí)現(xiàn):
private IPEndPoint ServerInfo;
private Socket ClientSocket;
private Byte[] MsgBuffer;//信息接收緩存
private Byte[] MsgSend; //信息發(fā)送存儲(chǔ)
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
MsgBuffer = new Byte[65535];
MsgSend = new Byte[65535];
this.UserName.Text =Environment.MachineName;
ServerInfo = new IPEndPoint (IPAddress.Parse(this.ServerIP.Text),Convert.ToInt32(this.ServerPort.Text));
ClientSocket.Connect(ServerInfo);
ClientSocket.Send (Encoding.Unicode.GetBytes (" 用 戶: " + this.UserName.Text + " 進(jìn)入系統(tǒng)! "));
ClientSocket.BeginReceive (MsgBuffer, 0, MsgBuffer.Length,SocketFlags.None, new AsyncCallback(ReceiveCallBack), null);
本文討論了Socket 的運(yùn)行機(jī)制以及其在C# 編程中的設(shè)計(jì)以及相關(guān)技術(shù)功能,Socket 作為一種應(yīng)用程序接口其在實(shí)際應(yīng)用中將底層的相關(guān)通信協(xié)議等各種技術(shù)封裝在程序背后, 為開(kāi)發(fā)人員提供了快速、高效的開(kāi)發(fā)方式。 討論其運(yùn)行機(jī)制,對(duì)開(kāi)發(fā)和技術(shù)維護(hù)有實(shí)際意義。
[1]胡晶晶,魯漫紅.基于Java Socket 的聊天室系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[J].微處理機(jī),2010,5:66-70.
[2]周譚凱,馬玉祥.網(wǎng)絡(luò)通信編程架構(gòu)研究[J].電子科技,2005(12).
[3]寇海洲,宗慧.利用Socket 實(shí)現(xiàn)被動(dòng)方式實(shí)時(shí)提醒系統(tǒng)設(shè)計(jì)[J].淮陰工學(xué)院學(xué)報(bào),2008(03).