在上一篇中,我列了一些常用的方法,可以說這些方法是一些輔助性的方法,對於分析網絡中的主機屬性非常有用。在這篇中,我將會介紹一下面向連接(TCP)socket編程,其中輔以實例,代碼可供下載。
對於TCP的Socket編程,主要分二部分:
一、服務端Socket偵聽:
服務端Socket偵聽主要分以下幾個步驟,按照以下幾個步驟我們可以很方便的建立起一個Socket偵聽服務,來偵聽嘗試連接到該服務器的客戶Socket,從而建立起連接進行相關通訊。
1、創建IPEndPoint實例,用於Socket偵聽時綁定
2、創建套接字實例
2 serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
這裏創建的時候用ProtocolType.Tcp,表示建立一個面向連接(TCP)的Socket。
3、將所創建的套接字與IPEndPoint綁定
2 serverSocket.Bind(ipep);
4、設置套接字爲收聽模式
2 serverSocket.Listen(10);
以上這四步,我們已經建立了Socket的偵聽模式,下面我們就來設置怎麼樣來獲取客戶Socket連接的實例,以及連接後的信息發送。
5、在套接字上接收接入的連接
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、 在套接字上接收客戶端發送的信息和發送信息
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實例和套接字
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、將套接字連接到遠程服務器
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、接收信息
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、發送信息
2
3 byte[] data = new byte[1024];
4 data = Encoding.ASCII.GetBytes(txtClient.Text);
5 clientSocket.Send(data, data.Length, SocketFlags.None);
客戶端的發送信息和接收信息跟服務器的接收發送是一樣的,只不過一個是偵聽模式而另一個是連接模式。
以下是程序的運行界面,這些在源碼下載裏都可以看到:
1、服務端界面:
2、客戶端界面: