zoukankan      html  css  js  c++  java
  • 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

                          从上面代码来看,发送端的代码也并不是很繁杂,当然上面所写的代码也只是实现了几个简单的发送与接收的功能。到这里为止一个简单的发送与接收及收接后返回就已完成了,上述代码若有何不当之处,可在评论中提出来。

              

                

  • 相关阅读:
    核心数据类型
    Python入门
    [多校联考2019(Round 4 T2)][51nod 1288]汽油补给(ST表+单调栈)
    [Codeforces 1228E]Another Filling the Grid (排列组合+容斥原理)
    [luogu5339] [TJOI2019]唱、跳、rap和篮球(容斥原理+组合数学)(不用NTT)
    用生成函数推导数列的通项公式
    [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增)
    [BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增)
    [BZOJ4444] [Luogu 4155] [LOJ 2007] [SCOI2015]国旗计划(倍增)
    倍增好题记录
  • 原文地址:https://www.cnblogs.com/lvlinlv/p/7880385.html
Copyright © 2011-2022 走看看