版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、C#Socket多線程編程實例時間:2010-09-0523:42來源:未知作者:admin點擊:1073次我要投稿高質(zhì)量的ASP.NET空間,完美支持1.0/2.0/3.5/4.0/MVC等C#g微軟隨著VS.net新推出的一門語言。它作為一門新興的語言,有著C+勺強健,乂有著VB等的RAD特性。而且,微軟推出C虻要的目的是為了對抗Sun公司的Java。大家都知道Java語言的強大功能,尤其在網(wǎng)絡(luò)編程方面。丁是,C皎網(wǎng)絡(luò)編程方面也自然不甘落后丁人。本文就向大家介紹一下C#F實現(xiàn)套接字(Sockets)編程的一些基本知識,以期能使大家對此有個大致了解。首先,我向大家介紹一下套接字的概念。套接字
2、基本概念:套接字是通信的基石,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元??梢詫⑻捉幼挚醋鞑煌鳈C問的進(jìn)程進(jìn)行雙向通信的端點,它構(gòu)成了單個主機內(nèi)及整個網(wǎng)絡(luò)間的編程界面。套接字存在丁通信域中,通信域是為了處理一般的線程通過套接字通信而引進(jìn)的一種抽象概念。套接字通常和同一個域中的套接字交換數(shù)據(jù)(數(shù)據(jù)交換也可能穿越域的界限,但這時一定要執(zhí)行某種解釋程序)。各種進(jìn)程使用這個相同的域互相之間用Internet協(xié)議簇來進(jìn)行通信。套接字可以根據(jù)通信性質(zhì)分類,這種性質(zhì)對丁用戶是可見的。應(yīng)用程序一般僅在同一類的套接字間進(jìn)行通信。不過只要底層的通信協(xié)議允許,不同類型的套接字問也照樣可以通信。套接字有兩種不同的
3、類型:流套接字和數(shù)據(jù)報套接字。套接字工作原理:要通過互聯(lián)網(wǎng)進(jìn)行通信,你至少需要一對套接字,其中一個運行丁客戶機端,我們稱之為ClientSocket,另一個運行丁服務(wù)器端,我們稱之為ServerSocket。根據(jù)連接啟動的方式以及本地套接字要連接的目標(biāo),套接字之間的連接過程可以分為三個步驟:服務(wù)器監(jiān)聽,客戶端請求,連接確認(rèn)。所謂服務(wù)器監(jiān)聽,是服務(wù)器端套接字并不定位具體的客戶端套接字,而是處丁等待連接的狀態(tài),實時監(jiān)控網(wǎng)絡(luò)狀態(tài)。所謂客戶端請求,是指由客戶端的套接字提出連接請求,要連接的目標(biāo)是服務(wù)器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號
4、,然后就向服務(wù)器端套接字提出連接請求。所謂連接確認(rèn),是指當(dāng)服務(wù)器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請求,它就響應(yīng)客戶端套接字的請求,建立一個新的線程,把服務(wù)器端套接字的描述發(fā)給客戶端,一旦客戶端確認(rèn)了此描述,連接就建立好了。而服務(wù)器端套接字繼續(xù)處丁監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請求。C呻的套接字編程實例:通過向大家簡單的介紹套接字的基本概念和實現(xiàn)套接字編程的基本原理,我想大家對套接字編程已有了初步的了解。不過,上面介紹的僅僅是基本概念和原理,要真正運用還是需要一定的工作的。對基本概念和原理的真正理解的最好方法莫過丁自己動手做一個實例,下面我就向大家介紹一個很好的用C就現(xiàn)套接
5、字編程的實例一一聊天室程序。本程序是基丁C/S(服務(wù)器/客戶端)構(gòu)架的,程序包含一個服務(wù)器端的應(yīng)用程序和一個客戶端的應(yīng)用程序。首先,在服務(wù)器上運行服務(wù)器端的應(yīng)用程序,該程序一運行就開始服務(wù)器監(jiān)聽。然后,在客戶機上就可以打開客戶端的應(yīng)用程序。程序打開后可以與服務(wù)器端應(yīng)用程序進(jìn)行連接,即進(jìn)行客戶端請求。在連接確認(rèn)后,客戶端用戶可以和其他的客戶端用戶進(jìn)行聊天。客戶端人數(shù)沒有限制,同時還支持“悄悄話”聊天模式,支持聊天記錄。所以這是一個學(xué)習(xí)套接字編程的相當(dāng)不錯的例子。而且,程序中為了處理每個客戶端的信息還用到了多線程機制。在每個客戶端與服務(wù)器端連接成功后,它們之間就建立一個線程。這樣運用了多線程之后,
6、客戶端之間就不會相互影響,即使其中一個出了錯誤也不會影響到另一個。下面,我就向大家具體介紹該實例:服務(wù)器端程序:1 .打開VS.net,新建一個C舶勺模板為“Windows應(yīng)用程序”的項目,不妨命名為“ChatServer”。2 .布置界面。只需在界面上添加一個ListBox控件即可,該控件主要用丁顯示客戶端的用戶的一些信息的。圖象如下:3 .服務(wù)器端程序的代碼編寫。對丁服務(wù)器端,主要的作用是監(jiān)聽客戶端的連接請求并確認(rèn)其請求。程序一開始便打開一個StartListening()線程。privatevoidStartListening()listener=newTcpListener(liste
7、nport);listener.Start();while(true)trySockets=listener.AcceptSocket();clientsocket=s;clientservice=newThread(newThreadStart(ServiceClient);clientservice.Start();catch(Exceptione)Console.WriteLine(e.ToString();該線程是一直處于運行狀態(tài)的。當(dāng)服務(wù)器端接收到一個來自客戶端的連接請求后,它就打開一個ServiceClient()線程來服務(wù)客戶端。當(dāng)一個連接被建立后,每個客戶端就被賦予一個屆于它自
8、己的套接字。同時,一個Client類的對象被建立。該對象包含了客戶端的一些相關(guān)信息,該信息被保存在一個數(shù)組歹0表中。Client類如下:usingSystem;usingSystem.Threading;namespaceChatServerusingSystem.Net.Sockets;usingSystem.Net;III/Client的摘要說明。IIIpublicclassClientprivateThreadclthread;privateEndPointendpoint;privatestringname;privateSocketsock;publicClient(string_n
9、ame,EndPoint_endpoint,Thread_thread,Socket_sock)IITODO:在此處添加構(gòu)造函數(shù)邏輯clthread=_thread;endpoint=_endpoint;name=_name;sock=_sock;publicoverridestringToString()returnendpoint.ToString()+":"+name;publicThreadCLThreadgetreturnclthread;setclthread=value;publicEndPointHostgetreturnendpoint;setendpoi
10、nt=value;publicstringNamegetreturnname;setname=value;publicSocketSockgetreturnsock;setsock=value;程序的主體部分應(yīng)是ServiceClient()函數(shù)。該函數(shù)是一個獨立的線程,其主要部分是一個while循環(huán)。在循環(huán)體內(nèi),程序處理各種客戶端命令。服務(wù)器端接收來自客戶端的以ASCII碼給出的字符申,其中包含了一個“|”形式的分隔符。字符申中“|”以前的部分就是具體的命令,包括CONNCHATPRIV、GON四種類型。CONNfr令建立一個新的客戶端連接,將現(xiàn)有的用戶列表發(fā)送給新用戶并告知其他用戶有一個新
11、用戶加入。CHA而令將新的信息發(fā)送給所有用戶。PRIV命令將悄悄話發(fā)送給某個用戶。GONE命令從用戶列表中除去一個已離開的用戶并告知其他的用戶某某已經(jīng)離開了。同時,GON命令可以設(shè)置布爾型的變量keepalive為false從而結(jié)束與客戶端連接的線程。ServiceClient()函數(shù)如下:privatevoidServiceClient()Socketclient=clientsocket;boolkeepalive=true;while(keepalive)Bytebuffer=newByte1024;client.Receive(buffer);stringclientcommand=S
12、ystem.Text.Encoding.ASCII.GetString(buffer);stringtokens=clientcommand.Split(newChar'|');Console.WriteLine(clientcommand);if(tokens0="CONN")for(intn=0;nClientcl=(Client)clientsn;SendToClient(cl,"JOIN|"+tokens1);EndPointep=client.RemoteEndPoint;Clientc=newClient(tokens1,ep
13、,clientservice,client);clients.Add(c);stringmessage="LIST|"+GetChatterList()+"rn"SendToClient(c,message);lbClients.Items.Add(c);if(tokens0="CHAT")for(intn=0;nClientcl=(Client)clientsn;SendToClient(cl,clientcommand);if(tokens0="PRIV")stringdestclient=tokens3;fo
14、r(intn=0;nClientcl=(Client)clientsn;if(cl.Name.CompareTo(tokens3)=0)SendToClient(cl,clientcommand);if(cl.Name.CompareTo(tokens1)=0)SendToClient(cl,clientcommand);if(tokens0="GONE")intremove=0;boolfound=false;intc=clients.Count;for(intn=0;nClientcl=(Client)clientsn;SendToClient(cl,clientcom
15、mand);if(cl.Name.CompareTo(tokens1)=0)remove=n;found=true;lbClients.Items.Remove(cl);if(found)clients.RemoveAt(remove);client.Close();keepalive=false;Form1.cs文件)程序運這樣,服務(wù)器端程序就基本完成了。(其他略次要的代碼可以參見源代碼中的行圖示如下:客戶端程序:1 .打開VS.net,新建一個C舶勺模板為“Windows應(yīng)用程序”的項目,不妨命名為ChatClient”。2 .布置界面。往界面上添加一個ListBox控件(用丁顯示用戶歹U
16、表),一個RichTextBox控件(用丁顯示聊天消息以及系統(tǒng)消息),一個TextBox控件(用丁發(fā)送消息),一個CheckBox控件(確定是否為悄悄話),一個StatusBar控件以及四個Button控件(分別為“連接”、“斷開連接”、“開始記錄”、“發(fā)送”)。各個控件的屆性設(shè)置可以參見源代碼中的具體設(shè)置,這里從略。界面設(shè)計好后的圖象如下:JCI2S1ip111|J111ll|IUIIIIBIII.011061Emilv12TD.Q.1IQ5Sfitt:10&9Bq。”127.0.011060Zraii上傳于【新客網(wǎng)mn.cowj3 .客戶端程序的代碼編寫。當(dāng)客戶端
17、試圖和服務(wù)器端進(jìn)行連接時,一個連接必須建立而且得向服務(wù)器端進(jìn)行注冊。EstablishConnection()函數(shù)運用一個TcpClient來和服務(wù)器端取得連接,同時創(chuàng)建一個Networkstream來發(fā)送消息。還有,端口號和服務(wù)器端的是保持一致的,均為5555。EstablishConnection()函數(shù)如下:privatevoidEstablishConnection()statusBar1.Text="正在連接到服務(wù)器”;tryclientsocket=newTcpClient(serveraddress,serverport);ns=clientsocket.GetStre
18、am();sr=newstreamReader(ns);connected=true;catch(Exception)MessageBox.Show('不能連接到服務(wù)器!","錯誤",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);statusBar1.Text="已斷開連接”;在和服務(wù)器端連接成功后,程序就用RegisterWithServer()函數(shù)向服務(wù)器端發(fā)送一個CONNfir令。該命令先是發(fā)送該用戶的名稱,然后從服務(wù)器端獲得其他所有用戶的列表,所有用戶列表是在ListBox控件中顯示的。
19、該函數(shù)如下:privatevoidRegisterWithServer()trystringcommand="CONN|"+ChatOut.Text;Byteoutbytes=System.Text.Encoding.ASCII.GetBytes(command.ToCharArray();ns.Write(outbytes,0,outbytes.Length);stringserverresponse=sr.ReadLine();serverresponse.Trim();stringtokens=serverresponse.Split(newChar'|
20、9;);if(tokens0="LIST")statusBar1.Text="已連接”;btnDisconnect.Enabled=true;for(intn=1;nlbChatters.Items.Add(tokensn.Trim(newchar'r','n');this.Text=clientname+":已連接到服務(wù)器”;catch(Exception)(MessageBox.Show('注冊時發(fā)生錯誤!","錯誤",MessageBoxButtons.OK,MessageBox
21、Icon.Exclamation);在此之后,當(dāng)然就是用戶之間的聊天了,由ReceiveChat()函數(shù)來完成。該函數(shù)是一個獨立的線程,它處理所有用戶獲得的消息和用戶發(fā)送的消息。它主要處理了CHATPRMJOIN、GONEQU99再命令,處理的方法和服務(wù)器端的類似。具體函數(shù)實現(xiàn)如下:privatevoidReceiveChat()(boolkeepalive=true;while(keepalive)(try(Bytebuffer=newByte2048;ns.Read(buffer,0,buffer.Length);stringchatter=System.Text.Encoding.ASC
22、II.GetString(buffer);stringtokens=chatter.Split(newChar'|');if(tokens0="CHAT")rtbChatIn.AppendText(tokens1);if(logging)logwriter.WriteLine(tokens1);if(tokens0="PRIV")rtbChatIn.AppendText("Privatefrom");rtbChatIn.AppendText(tokens1.Trim();rtbChatIn.AppendText(tok
23、ens2+"rn");if(logging)logwriter.Write("Privatefrom");logwriter.Write(tokens1.Trim();logwriter.WriteLine(tokens2+"rn");if(tokens0="JOIN")rtbChatIn.AppendText(tokens1.Trim();rtbChatIn.AppendText("hasjoinedtheChatrn");if(logging)logwriter.WriteLine(toke
24、ns1+"hasjoinedtheChat");stringnewguy=tokens1.Trim(newchar('r','n');IbChatters.Items.Add(newguy);if(tokens0="GONE")(rtbChatIn.AppendText(tokens1.Trim();rtbChatIn.AppendText("haslefttheChatrn");if(logging)(logwriter.WriteLine(tokens1+"haslefttheChat&q
25、uot;);lbChatters.Items.Remove(tokens1.Trim(newchar'r','n');if(tokens0="QU99v")ns.Close();clientsocket.Close();keepalive=false;statusBar1.Text="服務(wù)器端已停止"connected=false;btnSend.Enabled=false;btnDisconnect.Enabled=false;catch(Exception)通過以上的一些函數(shù),客戶端程序之間就可以進(jìn)行自由地聊天了,各個
26、用戶之間還可以互相發(fā)送悄悄話。所以程序已經(jīng)實現(xiàn)了聊天室的基本功能了,不過最后各個用戶還要正常地退出,那就要用到QuitChat()函數(shù)了。該函數(shù)的具體實現(xiàn)如下:privatevoidQuitChat()if(connected)trystringcommand="GONE|"+clientname;Byteoutbytes=System.Text.Encoding.ASCII.GetBytes(command.ToCharArray();ns.Write(outbytes,0,outbytes.Length);clientsocket.Close();catch(Excep
27、tion)if(logging)logwriter.Close();if(receive!=null&&receive.IsAlive)receive.Abort();this.Text="客戶端";到此為止,客戶端程序的主要部分都已經(jīng)介紹完畢。還有一些按鈕控件的消息處理函數(shù)可以參見源代碼。同時,程序中還有一個聊天記錄功能,該功能和現(xiàn)在流行的聊天軟件的記錄功能類似。不過限丁篇幅,在這里就不一一介紹了,有興趣的讀者可以研究一下本文后面的源代碼。這樣,客戶端程序就完成了。程序運行圖示如下:總結(jié):本文向大家初步介紹了套接字的基本概念和實現(xiàn)套接字編程的基本原理,還通
28、過一個很好的實例向大家展示了在C砰進(jìn)行套接字編程的實現(xiàn)方法和一些編程技巧。從中,我們不難發(fā)現(xiàn)運用C鼬行套接字編程乃至網(wǎng)絡(luò)編程有許多優(yōu)越之處。實例程序?qū)崿F(xiàn)的思路活晰明了而且通俗易懂,是一個相當(dāng)不錯的例子,希望各位能好好研讀。同時還希望大家能進(jìn)一步完善該程序,使之功能更強大、界面更友好。在此之后,當(dāng)然就是用戶之間的聊天了,由ReceiveChat()函數(shù)來完成。該函數(shù)是一個獨立的線程,它處理所有用戶獲得的消息和用戶發(fā)送的消息。它主要處理了CHATPRMJOIN、GONEQU99再命令,處理的方法和服務(wù)器端的類似。具體函數(shù)實現(xiàn)如下:privatevoidReceiveChat()boolkeepal
29、ive=true;while(keepalive)tryBytebuffer=newByte2048;ns.Read(buffer,0,buffer.Length);stringchatter=System.Text.Encoding.ASCII.GetString(buffer);stringtokens=chatter.Split(newChar('|');if(tokens0="CHAT")(rtbChatIn.AppendText(tokens1);if(logging)logwriter.WriteLine(tokens1);if(tokens0=
30、"PRIV")(rtbChatIn.AppendText("Privatefrom");rtbChatIn.AppendText(tokens1.Trim();rtbChatIn.AppendText(tokens2+"rn");if(logging)(logwriter.Write("Privatefrom");logwriter.Write(tokens1.Trim();logwriter.WriteLine(tokens2+"rn");if(tokens0="JOIN"
31、)(rtbChatIn.AppendText(tokens1.Trim();rtbChatIn.AppendText("hasjoinedtheChatrn");if(logging)(logwriter.WriteLine(tokens1+"hasjoinedtheChat");stringnewguy=tokens1.Trim(newchar'r','n');lbChatters.Items.Add(newguy);if(tokens0="GONE")rtbChatIn.AppendText(tokens1.Trim();rtbChatIn.AppendText("haslefttheChatrn");if(logging)logwriter.WriteLine(tokens1+"hasleft
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《學(xué)前教育概述》課件
- 單位管理制度集合大合集【人力資源管理篇】十篇
- 單位管理制度分享匯編【員工管理篇】十篇
- 單位管理制度分享大全【人員管理篇】
- 單位管理制度范例選集【員工管理】
- 單位管理制度范例合集【人力資源管理篇】十篇
- 單位管理制度呈現(xiàn)合集【員工管理篇】
- 單位管理制度呈現(xiàn)大合集【人事管理】十篇
- 《微點精析》考向19 文化常識 高考語文一輪復(fù)習(xí)考點微專題訓(xùn)練(原卷+解析)
- 第4單元 民族團結(jié)與祖國統(tǒng)一(B卷·能力提升練)(解析版)
- 教練技術(shù)CP理論PPT課件
- 機械工程學(xué)報標(biāo)準(zhǔn)格式
- 濕法脫硫用水水質(zhì)要求
- 東南大學(xué)文科揭榜掛帥重大平臺績效考核表
- 城管局個人工作總結(jié)
- 鉑銠合金漏板.
- (完整版)建筑力學(xué)(習(xí)題答案)
- 少年宮籃球活動教案
- 國有建設(shè)企業(yè)《大宗材料及設(shè)備采購招標(biāo)管理辦法》
- 民間秘術(shù)絕招大全
- (完整版)展廳展館博物館美術(shù)館設(shè)計標(biāo)招標(biāo)評分細(xì)則及打分表
評論
0/150
提交評論