C# Socket 發送&接收&返回


             因為工作比較忙,好久沒有寫過博客了,最近因項目需求,需要用到Socket來進行通信,簡單寫了幾個例子,記錄一下,代碼很簡單,無非就是接收與發送,以及接收到數據后返回一個自定義信息,也可以說是發送。

             先來簡單寫一個接收端的樣例,因為Socket需要監聽主機上的某個可用端口,在監聽開始之前並不是很清楚要監聽的某個端口是否被占用,可以在CMD或Powershell中輸入netstat -ano 進行查看,但這樣的話在每次使用一個端口之前都需要這樣操作,相對來講比較繁瑣。當然除此之外我們也可以通過 IPGlobalProperties來獲取本機的網絡連接的信息,並通過GetActiveTcpListeners找到已用端口,進而可以知道所需的端口是否已被占用,完成代碼如下:

 1       public static bool PortIsUse(int port)
 2         {
 3             bool isUse = false;
 5             IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
 6             IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();//找到已用端口
 8             foreach (IPEndPoint endPoint in ipEndPoints)
 9             {
10                 if (endPoint.Port == port)//判斷是否存在
11                 {
12                     isUse= true;
13                     break;
14                 }
15             }
16             return isUse;
17         }

              在做好准備工作后,開始來寫接收端代碼,首先得定義一個TcpListener對象來監聽本地的某個端口,比如我要監聽本地的1111端口那么代碼可以寫為:

     TcpListener tcpl = new TcpListener(new IPAddress(new byte[] { 127, 0, 0, 1 }), 1111);//定義一個TcpListener對象監聽本地的1111端口

       在監聽之前先調用之前寫的方法,檢查一下端口是否被占用,在定義好TcpListener后就可以調用該類的Start方法開始監聽,接收端完整代碼如下:

          TcpListener tcpl = new TcpListener(new IPAddress(new byte[] { 127, 0, 0, 1 }), 1111);//定義一個TcpListener對象監聽本地的1111端口
          tcpl.Start();//監聽開始
              while (true)
              {
                  Socket s = tcpl.AcceptSocket();//掛起一個Socket對象
                  string remote = s.RemoteEndPoint.ToString();//獲取發送端的IP及端口轉為String備用
                  Byte[] stream = new Byte[1024];
                  s.Receive(stream);//接收發送端發過來的數據,寫入字節數組
                 //BGW_Handle.ReportProgress(1, "接收來自[" + remote + "]信息");
                 string _data = Encoding.UTF8.GetString(stream);//將字節數據數組轉為String
                 s.Send(stream);//將接收到的內容,直接返回接收端
                 s.Shutdown(SocketShutdown.Both);
             }
             tcpl.Stop();//停止監聽

        接收端代碼並沒有很多,看起來也不是很復雜,在啟動監聽后,掛起一個Socket,並等待消息到達,在收到消息時,使用Receive方法將收到的消息寫入到Byte數組中,並在后續中直接將所收到的內容,轉為String,此時調用Socket的Send方法,將收到的數據直接回送給發送端,值得注意的在上述代碼中我使用了一個死循環while(true),在實際項目中,要考慮到這個循環所帶來的一系列問題,如阻塞主線程,UI線程,檢測到后續代碼無法訪問等,在應用到實際項目時,還要做一定的修改。             

       在接收端准備好后,開始來寫發送端代碼,因為發送端不需要監聽端口,所以就不用再定義一個TcpListener對象,也不需要檢查所用的端口是否已被占用,此時我們可以直接初始化一個Socket及將要連接的IPEndPoint對象,在定義Socket時指定其尋址方案為AddressFamily.InterNetwork,即通過IPV4來尋址,並指定類型為SocketType.Stream,即支持可靠、 雙向、 基於連接的字節流,在開始通信之前需要遠程主機的連接。同時指定Socket類支持的協議為TCP,代碼為:

               IPAddress ip = IPAddress.Parse("127.0.0.1");//接收端所在IP
               IPEndPoint ipEnd = new IPEndPoint(ip, 1111);//接收端所監聽的接口
               Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一個Socket對象

 

       在初始化完Socket對象后,即可使用Socket的Connect方法,嘗試連接,些前已定的接收端的地址及端口,在連接成功后,即可開始發送數據,並嘗試接收返回的數據,完整代碼如下:

 

             IPAddress ip = IPAddress.Parse("127.0.0.1");//接收端所在IP
             IPEndPoint ipEnd = new IPEndPoint(ip, 1111);//接收端所監聽的接口
             Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一個Socket對象
             try
             {
                 socket.Connect(ipEnd);//連接指定IP&端口
             }
             catch (SocketException e)
             {
                Console.WriteLine("連接失敗");
                 Console.WriteLine(e.ToString());
                 return;
             }
            socket.Send(Encoding.UTF8.GetBytes("1234567890"));//發送數據
           while (true)//定義一個循環接收返回數據
            {
                byte[] data = new byte[1024];
                socket.Receive(data);//接收返回數據
                 string  stringData = Encoding.UTF8.GetString(data);
                if (!string.IsNullOrWhiteSpace(stringData))
                {
                    Console.Write(stringData);
                    break;
                }
            }
socket.Shutdown(SocketShutdown.Both); socket.Close();//關閉Socket

                      從上面代碼來看,發送端的代碼也並不是很繁雜,當然上面所寫的代碼也只是實現了幾個簡單的發送與接收的功能。到這里為止一個簡單的發送與接收及收接后返回就已完成了,上述代碼若有何不當之處,可在評論中提出來。

          

            


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM