欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

简单的C# Socket通信实例

程序员文章站 2022-04-28 13:01:34
一、套接字(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

简单的C# Socket通信实例
 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

服务端后台代码

简单的C# Socket通信实例
  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

简单的C# Socket通信实例
 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

客户端后台代码

 

简单的C# Socket通信实例
  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

运行结果

 

简单的C# Socket通信实例

简单的C# Socket通信实例