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

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日

相关文章

  • Windows下C#的GUI窗口程序中实现调用Google Map的实例

    在Windows下使用C#开发GUI窗口程序的过程中,如果需要调用Google Map的API来实现一些地图相关的功能,可以按照以下步骤进行操作: 获取Google Map API 首先需要获取Google Map的API,可以通过访问Google Cloud Platform(https://console.cloud.google.com/apis)来获…

    C# 2023年6月7日
    00
  • Unity TextMeshPro实现富文本超链接默认字体追加字体

    下面是关于“Unity TextMeshPro 实现富文本超链接默认字体追加字体”的完整攻略: 背景介绍 在 Unity 项目中,TextMeshPro 是一款很常用的文本 UI 组件。它支持富文本、超链接、字体嵌入等功能,并且相比 Unity 自带的 Text 组件,TextMeshPro 更加易用、性能更好。我们在项目中经常需要使用到富文本超链接,但默认…

    C# 2023年6月3日
    00
  • C#实现语音播报功能

    首先需要明确的是,实现语音播报功能需要使用语音合成技术,而C#中的一个常用的语音合成接口就是System.Speech.Synthesis。 下面是实现语音播报的完整步骤: 1. 添加System.Speech.Synthesis引用 打开Visual Studio的解决方案,右键点击项目,选择“添加”->“引用”。在弹出的对话框中,找到“System…

    C# 2023年5月14日
    00
  • .NET Core类库项目中读取appsettings.json配置的方法

    首先,需要在.NET Core类库项目中引用Microsoft.Extensions.Configuration.Json包。可以通过NuGet包管理器或者NuGet控制台安装。 接下来,创建appsettings.json文件,并添加所需的配置信息,如下所示: { "AppSettings": { "ConnectionStr…

    C# 2023年6月3日
    00
  • asp.net 操作excel的实现代码

    下面我来详细讲解一下“ASP.NET操作Excel的实现代码”的完整攻略,包含以下几个部分: 了解ASP.NET操作Excel的前提条件 使用C#代码操作Excel文件 使用EPPlus操作Excel文件 实例说明:导入Excel数据到ASP.NET网站 实例说明:导出ASP.NET网站数据到Excel文件 了解ASP.NET操作Excel的前提条件 在使用…

    C# 2023年5月31日
    00
  • C#多线程学习(一) 多线程的相关概念

    C#多线程学习(一) 多线程的相关概念 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。 什么是线程? 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等), 但代码区是共享的,即不同的线程可以执行同样的函数。 什么是多线程? 多线程是指程序…

    C# 2023年4月17日
    00
  • C# 10个常用特性汇总

    C# 10个常用特性汇总 在本文中,我们将介绍 C# 中的10个常用特性及其用例,包括: 可空引用类型(Nullable reference types) 模式匹配(Pattern matching) 捕获块(Catch block) 局部函数(Local functions) 海象运算符(Null coalescing assignment operato…

    C# 2023年6月7日
    00
  • 浅谈C#索引器

    浅谈C#索引器 什么是C#索引器 C#索引器是一种特殊的属性,它允许类或结构使用类似于数组访问其实例的元素。在使用索引器时,可以通过索引来访问类或结构中定义的元素。在C#中,索引器是由get和set访问器定义的特殊属性,可以通过类或结构的名称来访问。 索引器语法 以下是C#索引器的基本语法: public datatype this[int index] {…

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