在上一篇中,我列了一些常用的方法,可以說這些方法是一些輔助性的方法 ,對於分析網絡中的主機屬性非常有用。在這篇中,我將會介紹一下面向連接( TCP)socket編程,其中輔以實例,代碼可供下載。
對於TCP的Socket編 程,主要分二部分:
一、服務端Socket偵聽:
服務端Socket偵聽 主要分以下幾個步驟,按照以下幾個步驟我們可以很方便的建立起一個Socket偵 聽服務,來偵聽嘗試連接到該服務器的客戶Socket,從而建立起連接進行相關通 訊。
1、創建IPEndPoint實例,用於Socket偵聽時綁定
1IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 6001);
2、創建套接字實例
1//創建一個套接字
這裡創建的時候用 ProtocolType.Tcp,表示建立一個面向連接(TCP)的Socket。
2 serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
3、將所創 建的套接字與IPEndPoint綁定
1 //將所創建的套接字與 IPEndPoint綁定
4、設置套接字為收聽模式
2 serverSocket.Bind(ipep);
1//設置套接字為收聽模式
2 serverSocket.Listen(10);
以上這四步,我們已經建立了 Socket的偵聽模式,下面我們就來設置怎麼樣來獲取客戶Socket連接的實例,以 及連接後的信息發送。
5、在套接字上接收接入的連接
1while (true)
2 {
3 try
4 {
5 //在套接字上接收接入的連接
6 clientSocket = serverSocket.Accept();
7 clientThread = new Thread(new ThreadStart (ReceiveData));
8 clientThread.Start();
9 }
10 catch (Exception ex)
11 {
12 MessageBox.Show ("listening Error: " + ex.Message);
13 }
14 }
通過serverSocket.Accept()來接收 客戶Socket的連接請求,在這裡用循環可以實現該線程實時偵聽,而不是只偵聽 一次。當程序運行serverSocket.Accept()時,會等待,直到有客戶端Socket發 起連接請求時,獲取該客戶Socket,如上面的clientSocket。在這裡我用多線程 來實現與多個客戶端Socket的連接和通信,一旦接收到一個連接後,就新建一個 線程,執行ReceiveData功能來實現信息的發送和接收。
6、在套接字上 接收客戶端發送的信息和發送信息
1private void ReceiveData ()
2 {
3 bool keepalive = true;
4 Socket s = clientSocket;
5 Byte[] buffer = new Byte[1024];
6
7 //根據收聽到的客戶端套接字向客戶 端發送信息
8 IPEndPoint clientep = (IPEndPoint) s.RemoteEndPoint;
9 lstServer.Items.Add("Client: " + clientep.Address + "("+clientep.Port+") ");
10 string welcome = "Welcome to my test sever ";
11 byte[] data = new byte[1024];
12 data = Encoding.ASCII.GetBytes(welcome);
13 s.Send(data, data.Length, SocketFlags.None);
14
15 while (keepalive)
16 {
17 //在 套接字上接收客戶端發送的信息
18 int bufLen = 0;
19 try
20 {
21 bufLen = s.Available;
22
23 s.Receive(buffer, 0, bufLen, SocketFlags.None);
24 if (bufLen == 0)
25 continue;
26 }
27 catch (Exception ex)
28 {
29 MessageBox.Show ("Receive Error:" + ex.Message);
30 return;
31 }
32 clientep = (IPEndPoint)s.RemoteEndPoint;
33 string clientcommand = System.Text.Encoding.ASCII.GetString (buffer).Substring(0, bufLen);
34
35 lstServer.Items.Add(clientcommand + "("+clientep.Address + ":"+clientep.Port+")");
36
37 }
38
39 }
通過IPEndPoint clientep = (IPEndPoint)s.RemoteEndPoint;我們可以獲取連接上的遠程主機的 端口和IP地址,如果想查詢該主機的其它屬性如主機名等,可用於上一篇講的 Dns.GetHostByAddress(string ipAddress)來返回一個IPHostEntry對象,就可 以得到。另外我們要注意的是,通過Socket發送信息,必須要先把發送的信息轉 化成二進字進行傳輸,收到信息後也要把收到的二進字信息轉化成字符形式,這 裡可以通過Encoding.ASCII.GetBytes(welcome);和Encoding.ASCII.GetString (buffer).Substring(0, bufLen);來實現。
以上就是服務端Socket偵聽 模式的實現,只要有遠程客戶端Socket連接上後,就可以輕松的發送信息和接收 信息了。下面我們來看看客戶端Socket是怎麼連接上服務器的。
二、客 戶端連接
客戶端Socket連接相對來說比較簡單了,另外說明一下,在執 行客戶端連接前,服務端Socket偵聽必須先啟動,不然會提示服務器拒絕連接的 信息。
1、創建IPEndPoint實例和套接字
1 //創建一個套 接字
2 IPEndPoint ipep = new IPEndPoint (IPAddress.Parse("127.0.0.1"), 6001);
3 clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
這個跟服務端Socket 偵聽差不多,下面一步由服務端Socket的偵聽模式變成連接模式。
2、將 套接字連接到遠程服務器
1//將套接字與遠程服務器地址相連
2 try
3 {
4 clientSocket.Connect(ipep);
5 }
6 catch (SocketException ex)
7 {
8 MessageBox.Show("connect error: " + ex.Message);
9 return;
10 }
前面已說明,如果 在執行Socket連接時,服務器的Socket偵聽沒有開啟的話,會產生一個 SocketException異常,如果沒有異常發生,那恭喜你,你已經與服務器連接上 了,接下來就可以跟服務器通信了。
3、接收信息
1while (true)
2 {
3 //接收服務器信息
4 int bufLen = 0;
5 try
6 {
7 bufLen = clientSocket.Available;
8
9 clientSocket.Receive(data, 0, bufLen, SocketFlags.None);
10 if (bufLen == 0)
11 {
12 continue;
13 }
14 }
15 catch (Exception ex)
16 {
17 MessageBox.Show ("Receive Error:" + ex.Message);
18 return;
19 }
20
21 string clientcommand = System.Text.Encoding.ASCII.GetString(data).Substring (0, bufLen);
22
23 lstClient.Items.Add (clientcommand);
24
25 }
4、發送信息
1//向服務器發送信息
2
3 byte[] data = new byte[1024];
4 data = Encoding.ASCII.GetBytes(txtClient.Text);
5 clientSocket.Send(data, data.Length, SocketFlags.None);
客戶端的發送信息和接收信息跟服務器的接收發送是一樣的,只不過一個是偵聽 模式而另一個是連接模式。
以下是程序的運行界面,這些在源碼下載裡 都可以看到:
1、服務端界面:
2、客戶端界面:
好了,關於面向連接的Socket就講到這裡了,以實例為主,希望對那 些派得上用場的朋友能夠看得明白。另外提一下,這裡服務端開啟偵聽服務、客 戶端連接服務端都采用線程方式來實現,這樣服務端能夠跟多個客戶端同時通信 ,不用等候,當然還有另外一種方式可以實現那就是異步socket,關於這些可以 搜索博客園上的相關文章,已經有好多了。
本文配套源碼