面向連接的socket編程

 

  在上一篇中,我列了一些常用的方法,可以說這些方法是一些輔助性的方法,對於分析網絡中的主機屬性非常有用。在這篇中,我將會介紹一下面向連接(TCP)socket編程,其中輔以實例,代碼可供下載。
      對於TCP的Socket編程,主要分二部分:
      一、服務端Socket偵聽:
      服務端Socket偵聽主要分以下幾個步驟,按照以下幾個步驟我們可以很方便的建立起一個Socket偵聽服務,來偵聽嘗試連接到該服務器的客戶Socket,從而建立起連接進行相關通訊。
      1、創建IPEndPoint實例,用於Socket偵聽時綁定
         

1IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 6001);

      2、創建套接字實例
 

1//創建一個套接字
2            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  
      這裏創建的時候用ProtocolType.Tcp,表示建立一個面向連接(TCP)的Socket。

      3、將所創建的套接字與IPEndPoint綁定

1 //將所創建的套接字與IPEndPoint綁定
2            serverSocket.Bind(ipep);

      4、設置套接字爲收聽模式
 
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、客戶端界面:
      

      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章