C# 三种方式实现Socket数据接收

yizhihongxing

C#是一种基于对象的程序设计语言,可以使用它来实现Socket数据接收。在C#中,Socket可以通过三种方式进行数据接收,分别是:同步方式、异步方式和事件驱动方式。

  1. 同步方式

同步方式是一种阻塞式的接收方式,即程序执行在接收Socket数据的阶段会一直阻塞,直到数据接收完成后程序才会继续执行。

代码示例:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class SocketReceiver
{
    public static void Main()
    {
        // 创建Socket对象
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        // 绑定IP地址和端口号
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);
        listener.Bind(localEndPoint);

        // 开始监听连接请求
        listener.Listen(10);

        Socket handler = listener.Accept();

        // 接收数据
        byte[] bytes = new byte[1024];
        int bytesRec = handler.Receive(bytes);
        Console.WriteLine("接收到的消息: {0}", Encoding.ASCII.GetString(bytes, 0, bytesRec));

        // 关闭Socket
        handler.Shutdown(SocketShutdown.Both);
        handler.Close();
    }
}
  1. 异步方式

异步方式是一种非阻塞式的接收方式,即程序执行在接收Socket数据的阶段不会一直阻塞,而是可以继续执行其他任务,当数据接收完成后再处理接收到的数据。

代码示例:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

public class SocketReceiver
{
    private static ManualResetEvent receiveDone = new ManualResetEvent(false);

    public static void Main()
    {
        // 创建Socket对象
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        // 绑定IP地址和端口号
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);
        listener.Bind(localEndPoint);

        // 开始监听连接请求
        listener.Listen(10);

        while (true)
        {
            receiveDone.Reset();
            Console.WriteLine("等待连接...");
            listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
            receiveDone.WaitOne();
        }
    }

    public static void AcceptCallback(IAsyncResult ar)
    {
        receiveDone.Set();

        // 获取监听Socket对象
        Socket listener = (Socket)ar.AsyncState;

        // 创建连接
        Socket handler = listener.EndAccept(ar);

        // 开始异步接收数据
        StateObject state = new StateObject();
        state.workSocket = handler;
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
    }

    public static void ReceiveCallback(IAsyncResult ar)
    {
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        // 结束异步接收数据
        int bytesRead = handler.EndReceive(ar);
        if (bytesRead > 0)
        {
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
        }
        else
        {
            if (state.sb.Length > 1)
            {
                string content = state.sb.ToString();
                Console.WriteLine("接收到的消息: {0}", content);
            }
            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
        }
    }

    public class StateObject
    {
        public Socket workSocket = null;
        public const int BufferSize = 1024;
        public byte[] buffer = new byte[BufferSize];
        public StringBuilder sb = new StringBuilder();
    }
}
  1. 事件驱动方式

事件驱动方式也是一种非阻塞式的接收方式,与异步方式类似。事件驱动方式是基于事件的编程模型,程序通过订阅Socket的事件来进行数据接收和处理。

代码示例:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class SocketReceiver
{
    private static byte[] buffer = new byte[1024];
    private static Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    public static void Main()
    {
        // 绑定IP地址和端口号
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);
        listener.Bind(localEndPoint);

        // 开始监听连接请求
        listener.Listen(10);

        Console.WriteLine("等待连接...");
        Socket handler = listener.Accept();

        // 订阅数据接收事件
        handler.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), handler);
    }

    private static void ReceiveCallback(IAsyncResult ar)
    {
        Socket handler = (Socket)ar.AsyncState;

        // 结束异步接收数据
        int bytesRead = handler.EndReceive(ar);
        if (bytesRead > 0)
        {
            Console.WriteLine("接收到的消息: {0}", Encoding.ASCII.GetString(buffer, 0, bytesRead));
            handler.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), handler);
        }
        else
        {
            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
        }
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# 三种方式实现Socket数据接收 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • 轻松学习C#的运算符

    轻松学习C#的运算符 本文将会详细讲解C#中的常见运算符,包括算术运算符、赋值运算符、比较运算符、逻辑运算符以及位运算符。同时还将给出两条示例说明。 算术运算符 C#中的算术运算符包括+、-、*、/、%五种。 其中,+运算符用于执行加法运算,-运算符用于执行减法运算,*运算符用于执行乘法运算,/运算符用于执行除法运算,%运算符用于执行取模运算。 示例: in…

    C# 2023年6月1日
    00
  • Win10 20H1快速预览版18875更新后部分软件无法使用怎么办?

    下面是关于“Win1020H1快速预览版18875更新后部分软件无法使用怎么办?”的完整攻略,包含两个示例。 1. Win1020H1快速预览版18875更新后部分软件无法使用问题简介 在使用Win1020H1快速预览版18875时,可能会遇到部分软件无法使用的问题。这可能是由于更新后的系统不兼容某些软件或者更新过程中出现了错误导致的。下面是解决这个问题的步…

    C# 2023年5月15日
    00
  • c# 如何实现图片压缩

    要实现图片压缩,可以使用c#中的System.Drawing.Imaging命名空间中的Encoder类和EncoderParameter类。下面是具体的步骤: 1. 加载图片 首先,需要使用Image.FromFile()方法来加载原图像。例如,以下代码加载名为“original.jpg”的图像: Image originalImage = Image.F…

    C# 2023年6月6日
    00
  • 在C#和Java语言中for和foreach的区别详解

    在C#和Java语言中for和foreach的区别详解 在C#和Java语言中,for和foreach都是循环语句,但在使用方式和效率上有一些区别。下面详细讲解它们的区别。 for循环 for循环是一种常用的循环语句,用于在已知循环次数的情况下重复执行一段代码。其语法如下: for (初始化; 条件; 递增/递减) { //代码块 } for (初始化; 条…

    C# 2023年6月7日
    00
  • asp.net 生成随机密码的具体代码

    生成随机密码是一个常见的需求,特别是在ASP.NET的网站开发中更是经常用到。本文将详细讲解ASP.NET生成随机密码的具体代码。 一. 生成指定位数的随机密码 要生成指定位数的随机密码,可以使用Random类从字符集中随机抽取指定数量的字符来进行组合。这里给出的代码生成一个8位长度的随机密码: public static string GenerateRa…

    C# 2023年5月31日
    00
  • 数据库 数据类型float到C#类型decimal, float数据类型转化无效

    问题描述: 在将数据库中的float数据类型转换成C#的decimal类型时,有些数据会发生转化无效的情况。这是由于float数据类型的精度问题所导致的。本文将详细介绍如何解决这个问题,并提供两个演示示例。 解决步骤: 1.使用double类型进行过渡转换 当我们将数据库中的float类型转化成decimal类型时,可以使用double类型作为过渡类型。这是…

    C# 2023年5月15日
    00
  • 深入.net调用webservice的总结分析

    《深入.NET调用Web Service的总结分析》是一篇介绍.Net平台下调用Web服务的文章。其内容主要包括Web服务的概念介绍、使用.Net框架下的方式调用Web服务的具体步骤、调用WebService是需要注意的问题等。 概述 Web服务(Web service)是指通过Internet对外提供的可以被远程应用程序调用的程序接口。在.Net平台下可以…

    C# 2023年6月6日
    00
  • Asp.Net Cache缓存使用代码

    接下来我将为您讲解Asp.Net Cache缓存使用代码的完整攻略。 Asp.Net Cache缓存简介 首先,我们来了解一下Asp.Net Cache缓存。 缓存是一种常见的优化技术,通过将经常使用的数据缓存到内存中,以提高系统的性能和响应速度。而Asp.Net提供了一个Cache对象来实现缓存功能。 Asp.Net的Cache对象是一个全局对象,可以在所…

    C# 2023年5月31日
    00
合作推广
合作推广
分享本页
返回顶部