簡單的C# Socket通信實例

来源:https://www.cnblogs.com/TechnologyDictionary/archive/2019/02/22/10423068.html
-Advertisement-
Play Games

一、套接字(socket)概念 套接字(socket)是通信的基石,是支持TCP/IP協議的網路通信的基本操作單元。它是網路通信過程中端點的抽象表示,包含進行網路通信必須的五種信息:連接使用的協議,本地主機的IP地址,本地進程的協議埠,遠地主機的IP地址,遠地進程的協議埠。 應用層通過傳輸層進行 ...


一、套接字(socket)概念

       套接字(socket)是通信的基石,是支持TCP/IP協議的網路通信的基本操作單元。它是網路通信過程中端點的抽象表示,包含進行網路通信必須的五種信息:連接使用的協議,本地主機的IP地址,本地進程的協議埠,遠地主機的IP地址,遠地進程的協議埠。
  應用層通過傳輸層進行數據通信時,TCP會遇到同時為多個應用程式進程提供併發服務的問題。多個TCP連接或多個應用程式進程可能需要通過同一個 TCP協議埠傳輸數據。為了區別不同的應用程式進程和連接,許多電腦操作系統為應用程式與TCP/IP協議交互提供了套接字(Socket)介面。應 用層可以和傳輸層通過Socket介面,區分來自不同應用程式進程或網路連接的通信,實現數據傳輸的併發服務。

二、建立socket連接

       建立Socket連接至少需要一對套接字,其中一個運行於客戶端,稱為ClientSocket ,另一個運行於伺服器端,稱為ServerSocket 。
  套接字之間的連接過程分為三個步驟:伺服器監聽,客戶端請求,連接確認。

  1. 伺服器監聽:伺服器端套接字並不定位具體的客戶端套接字,而是處於等待連接的狀態,實時監控網路狀態,等待客戶端的連接請求 
  2. 客戶端請求:指客戶端的套接字提出連接請求,要連接的目標是伺服器端的套接字。為此,客戶端的套接字必須首先描述它要連接的伺服器的套接字,指出伺服器端套接字的地址和埠號,然後就向伺服器端套接字提出連接請求。
  3. 連接確認:當伺服器端套接字監聽到或者說接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把伺服器端套接字的描述發給客戶 端,一旦客戶端確認了此描述,雙方就正式建立連接。而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連接請求。

三、服務端與客戶端代碼

服務端前臺XMAL

 1 <Window x:Class="Socket通信.MainWindow"
 2          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6          xmlns:local="clr-namespace:Socket通信"
 7          mc:Ignorable="d"
 8          Title="服務端" Height="350" Width="525" Loaded="Window_Loaded" >
 9      <Grid>
10          <Grid.RowDefinitions>
11              <RowDefinition Height="50*"/>
12              <RowDefinition Height="190*"/>
13              <RowDefinition Height="81*"/>
14          </Grid.RowDefinitions>
15          <Grid Grid.Row="0">
16              <WrapPanel VerticalAlignment="Center">
17                  <Label Padding="5">IP:</Label>
18                  <TextBox Padding="3" Width="150" Name="IP"></TextBox>
19                  <Label Padding="5">Port:</Label>
20                  <TextBox Padding="3" Width="100" Name="Port"></TextBox>
21                  <Button Padding="3" Margin="3" Click="Start_View_Click">開始監聽</Button>
22                  <Button Padding="3" Margin="3" Click="Stop_Click">停止監聽</Button>
23              </WrapPanel>
24          </Grid>
25          <Grid Grid.Row="1">
26              <ListBox Name="ListConnet"></ListBox>
27          </Grid>
28          <Grid Grid.Row="2">
29              <Grid.ColumnDefinitions>
30                  <ColumnDefinition Width="405*"/>
31                  <ColumnDefinition Width="113*"/>
32              </Grid.ColumnDefinitions>
33             
34                  <TextBox Name="SentConnet"></TextBox>
35                  <Button Grid.Column="1" Click="Send_Click">發送</Button>
36           
37          </Grid>
38      </Grid>
39  </Window>
View Code

服務端後臺代碼

  1 using System;
  2  using System.Net;
  3  using System.Net.Sockets;
  4  using System.Text;
  5  using System.Threading;
  6  using System.Windows;
  7 
  8  
  9 
 10 namespace Socket通信
 11 {
 12      /// <summary>
 13      /// MainWindow.xaml 的交互邏輯
 14     /// </summary>
 15      public partial class MainWindow : Window
 16      {
 17          public MainWindow()
 18          {
 19              InitializeComponent();
 20          }
 21          Socket socketSend;
 22          private void Start_View_Click(object sender, RoutedEventArgs e)
 23          {
 24              try
 25               {
 26                  //點擊開始監聽時 在服務端創建一個負責監聽IP和埠號的Socket
 27                   Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 28                   IPAddress ip = IPAddress.Any;                //創建對象埠
 29                  IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(Port.Text));
 30                   socketWatch.Bind(point);//綁定埠號
 31                  ShowMsg("監聽成功!");
 32                   socketWatch.Listen(10);//設置監聽
 33                  //創建監聽線程
 34                   Thread thread = new Thread(Listen);
 35                    thread.IsBackground = true;
 36                    thread.Start(socketWatch);
 37              }
 38               catch { }
 39 
 40  
 41 
 42         }
 43   
 44          void Listen(object o)
 45           {
 46                try
 47                {
 48                   Socket socketWatch = o as Socket;
 49                    while (true)
 50                    {
 51                       socketSend = socketWatch.Accept();//等待接收客戶端連接
 52                      ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "連接成功!");
 53                      //開啟一個新線程,執行接收消息方法
 54                      Thread r_thread = new Thread(Received);
 55                       r_thread.IsBackground = true;
 56                       r_thread.Start(socketSend);
 57                   }
 58               }
 59               catch { }
 60          }
 61 
 62  
 63 
 64          /// <summary>
 65            /// 伺服器端不停的接收客戶端發來的消息
 66           /// </summary>
 67            /// <param name="o"></param>
 68            void Received(object o)
 69            {
 70               try
 71               {
 72                    Socket socketSend = o as Socket;
 73                   while (true)
 74                    {
 75                        //客戶端連接伺服器成功後,伺服器接收客戶端發送的消息
 76                     byte[] buffer = new byte[1024 * 1024 * 3];
 77                        //實際接收到的有效位元組數
 78                       int len = socketSend.Receive(buffer);
 79                        if (len == 0)
 80                        {
 81                            break;
 82                        }
 83                        string str = Encoding.UTF8.GetString(buffer, 0, len);
 84                        ShowMsg("接收到的客戶端數據:" + socketSend.RemoteEndPoint + ":" + str);
 85                    }
 86                }
 87                catch { }
 88            }
 89            /// <summary>
 90            /// 伺服器向客戶端發送消息
 91           /// </summary>
 92            /// <param name="str"></param>
 93            void Send(string str)
 94               {
 95                   byte[] buffer = Encoding.UTF8.GetBytes(str);
 96                   socketSend.Send(buffer);
 97               }
 98   
 99           void ShowMsg(string msg)
100           {
101              Dispatcher.Invoke(() => { ListConnet.Items.Add(msg + "\r\n"); });
102           }
103 
104  
105 
106         private void Send_Click(object sender, RoutedEventArgs e)
107         {
108              Send(SentConnet.Text.Trim());
109          }
110 
111         private void Window_Loaded(object sender, RoutedEventArgs e)
112          {
113          }
114          private void Stop_Click(object sender, RoutedEventArgs e)
115          {
116              socketSend.Close();
117              ShowMsg("已經停止監聽!");
118          }
119      }
120  }
View Code

客戶端前臺XMAL

 1 <Window x:Class="Socket_Client.MainWindow"
 2          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6          xmlns:local="clr-namespace:Socket_Client"
 7          mc:Ignorable="d"
 8          Title="客戶端" Height="350" Width="525">
 9     <Grid>
10          <Grid.RowDefinitions>
11              <RowDefinition Height="50*"/>
12              <RowDefinition Height="190*"/>
13              <RowDefinition Height="81*"/>
14          </Grid.RowDefinitions>
15          <Grid Grid.Row="0">
16              <WrapPanel VerticalAlignment="Center">
17                  <Label Padding="5">IP:</Label>
18                  <TextBox Padding="3" Width="150" Name="IP"></TextBox>
19                  <Label Padding="5">Port:</Label>
20                  <TextBox Padding="3" Width="100" Name="Port"></TextBox>
21                  <Button Padding="3" Margin="3" Click="Start_View_Click">連接</Button>
22                  <Button Padding="3" Margin="3" Click="Stop_Click">斷開連接</Button>
23              </WrapPanel>
24          </Grid>
25          <Grid Grid.Row="1">
26              <TextBox Name="ListConnet"></TextBox>
27          </Grid>
28          <Grid Grid.Row="2">
29              <Grid.ColumnDefinitions>
30                  <ColumnDefinition Width="405*"/>
31                  <ColumnDefinition Width="113*"/>
32              </Grid.ColumnDefinitions>
33 
34  
35 
36             <TextBox Name="SentConnet"></TextBox>
37              <Button Grid.Column="1" Click="Send_Click">發送</Button>
38 
39         </Grid>
40      </Grid>
41  </Window>
View Code

客戶端後臺代碼

 

  1 using System;
  2  using System.Collections.Generic;
  3  using System.Linq;
  4  using System.Net;
  5  using System.Net.Sockets;
  6  using System.Text;
  7  using System.Threading;
  8  using System.Threading.Tasks;
  9  using System.Windows;
 10  using System.Windows.Controls;
 11  using System.Windows.Data;
 12  using System.Windows.Documents;
 13  using System.Windows.Input;
 14  using System.Windows.Media;
 15  using System.Windows.Media.Imaging;
 16  using System.Windows.Navigation;
 17  using System.Windows.Shapes;
 18 
 19  
 20 
 21 namespace Socket_Client
 22  {
 23      /// <summary>
 24      /// MainWindow.xaml 的交互邏輯
 25     /// </summary>
 26      public partial class MainWindow : Window
 27      {
 28          public MainWindow()
 29          {
 30              InitializeComponent();
 31          }
 32          Socket socketSend;
 33 
 34  
 35 
 36         private void Start_View_Click(object sender, RoutedEventArgs e)
 37          {
 38              try
 39                {
 40                                  //創建客戶端Socket,獲得遠程ip和埠號
 41                     socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 42                      IPAddress ip = IPAddress.Parse(IP.Text);
 43                      IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(Port.Text));
 44                 
 45                      socketSend.Connect(point);
 46                      ShowMsg("連接成功!");
 47                                   //開啟新的線程,不停的接收伺服器發來的消息
 48                     Thread c_thread = new Thread(Received);
 49                      c_thread.IsBackground = true;
 50                      c_thread.Start();
 51                 }
 52               catch (Exception)
 53              {
 54                 ShowMsg("IP或者埠號錯誤...");
 55              }
 56             
 57 
 58  
 59 
 60         }
 61          void ShowMsg(string str)
 62           {
 63 
 64  
 65 
 66             Dispatcher.Invoke(() => { ListConnet.AppendText(str + "\r\n"); });
 67          }
 68          /// <summary>
 69           /// 接收服務端返回的消息
 70          /// </summary>
 71          void Received()
 72          {
 73              while (true)
 74              {
 75                try
 76                {
 77                     byte[] buffer = new byte[1024 * 1024 * 3];
 78                     //實際接收到的有效位元組數
 79                     int len = socketSend.Receive(buffer);
 80                     if (len == 0)
 81                     {
 82                         continue;
 83                       }
 84                      string str = Encoding.UTF8.GetString(buffer, 0, len);
 85                      ShowMsg("接收到的服務端數據:" + socketSend.RemoteEndPoint + ":" + str);
 86                  }
 87                  catch
 88                  {
 89 
 90  
 91 
 92                 }
 93             }
 94          }
 95 
 96  
 97 
 98         private void Send_Click(object sender, RoutedEventArgs e)
 99          {
100              try
101              {
102                       string msg = SentConnet.Text.Trim();
103                       byte[] buffer = new byte[1024 * 1024 * 3];
104                       buffer = Encoding.UTF8.GetBytes(msg);
105                       socketSend.Send(buffer);
106                }
107              catch { }
108 
109  
110 
111         }
112 
113         private void Stop_Click(object sender, RoutedEventArgs e)
114          {
115              socketSend.Close();
116              ShowMsg("連接已經斷開!");
117          }
118      }
119  }
View Code

運行結果

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ————— 當天上午 ————— 什麼是冒泡排序? 冒泡排序的英文Bubble Sort,是一種最基礎的交換排序。 大家一定都喝過汽水,汽水中常常有許多小小的氣泡,嘩啦嘩啦飄到上面來。這是因為組成小氣泡的二氧化碳比水要輕,所以小氣泡可以一點一點向上浮動。 而我們的冒泡排序之所以叫做冒泡排序,正是因為 ...
  • & x5B98;& x65B9;& x6587;& x6863;& x4E2D;& x5BF9;DataTrigger& x7684;& x4ECB;& x7ECD; Represents a trigger that applies property values or performs acti ...
  • 進程:進程是一個程式在電腦運行時,全部資源的合集叫進程 線程:是程式的最小執行單位,包含計算資源,任何一個操作的響應都是線程完成的。 多線程:多個線程併發執行 Thread 是.net框架封裝的一個類,描述線程的東西 同步和非同步都是描述方法的,所以需要使用委托。 同步方法:發起一個調用,一定等著計算 ...
  • 本文提供一個現成的範例下載,用 HTML 網頁 + jQuery Mobile,呼叫(調用) ASP.NET Web API 服務。 ...
  • 本文繼續介紹定時任務 Wpf.Quartz.Demo.3的一些小細節, 代碼也請前往第3節下載。 1.RichTextBox右鍵菜單 <RichTextBox.ContextMenu> <ContextMenu> <MenuItem Header="剪貼" Command="ApplicationC ...
  • 先把全部源碼上傳,只是一個Demo,希望大家指點一下不足之處,見本文底部。 1.設置界面 2.詳情頁面 好了,現在慢慢敘述裡面的一些方法。 3.實現拷貝的方法: (1) public static void LeftCopyRight(object left, object right) { var ...
  • 這個大概分為兩種情況:1-在同一程式集訪問該類;2-在不同的程式集訪問 A:同一程式集,使用微軟的創建對象的類:System.Activator: 先通過類名,獲取到類型,在使用用於創建本地或遠程對象的Activator類創建類型的實例: B:不同的程式集(同一程式集也可用):微軟的程式集抽象類提供 ...
  • 這篇文章說明瞭如何使用EPPlus在ASP.NET Core中導入和導出.xls/.xlsx文件(Excel)。在考慮使用.NET處理excel時,我們總是尋找第三方庫或組件。使用Open Office Xml格式(xlsx)讀取和寫入Excel 2007/2010文件的最流行的.net庫之一是EP ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...