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日

相关文章

  • 基于DateTime.ParseExact方法的使用详解

    基于DateTime.ParseExact方法的使用详解 简介 C#中的DateTime.ParseExact方法是将字符串转化为DateTime类型的一种常用方式。它能够根据特定的格式将字符串解析成DateTime类型的值。在实际开发中,我们常常会遇到将字符串转化为日期类型的需求,而DateTime.ParseExact方法能够帮助我们实现这一目的。下面将…

    C# 2023年6月1日
    00
  • Android实现横屏切换科学计算器

    Android实现横屏切换科学计算器攻略 介绍 在Android应用中实现横屏切换,能够提升用户体验,特别是在进行科学计算的时候。在横屏模式下,可以修改应用的布局,增加更多的控件和功能。本文将详细讲解如何实现在Android应用中实现横屏切换的科学计算器。 实现步骤 首先需要定义两种不同的布局文件,一种布局用于竖屏模式,另一种用于横屏模式。命名方式应该为: …

    C# 2023年6月7日
    00
  • C#编程中设置程序只可被运行一次的方法

    下面是详细讲解C#编程中设置程序只可被运行一次的方法的完整攻略。 问题描述 有时候我们的应用程序可能需要保证只能运行一次。比如某些每次只能打印一份报告的程序,如果不做限制,用户可能会不无节制的打印多份,造成资源浪费以及用户体验不佳等问题。那么如何在C#中实现一个程序只能运行一次的限制呢?下面将讲解两种方法。 方法一:使用命名管道 命名管道是一种高级IPC(进…

    C# 2023年5月15日
    00
  • C#算法函数:获取一个字符串中的最大长度的数字

    获取一个字符串中的最大长度的数字,可以通过以下算法函数来实现: 函数定义 public static int GetMaxNumberLength(string str) { string[] words = str.Split(new char[] { ‘ ‘, ‘,’, ‘.’, ‘?’, ‘!’ }, StringSplitOptions.Remove…

    C# 2023年6月8日
    00
  • C#向无窗口的进程发送消息

    下面是详细的讲解。 C#向无窗口的进程发送消息的完整攻略 在C#中,我们可以使用Windows API来向无窗口的进程发送消息。下面是完整的攻略。 1. 准备工作 要向无窗口的进程发送消息,我们需要知道目标进程的进程ID(PID)。可以使用Windows API中的Process.GetProcessesByName()方法获取指定名称的进程列表,然后根据需…

    C# 2023年6月6日
    00
  • C#获取机器码的方法详解(机器名,CPU编号,硬盘编号,网卡mac等)

    C#获取机器码的方法详解 在C#中,可以通过获取机器的特定信息来生成其唯一的机器码。具体可以获取的信息有机器名、CPU编号、硬盘编号、网卡mac等。下面我们分别介绍如何获取这些信息。 获取机器名 通过Environment.MachineName可以获取机器名,示例如下: string machineName = Environment.MachineNam…

    C# 2023年6月7日
    00
  • C#实现读取匿名对象属性值的方法示例总结

    针对此话题,下面我来详细讲解C#实现读取匿名对象属性值的方法示例总结的完整攻略。 什么是匿名对象 匿名对象是一种没有具体类名的对象,可以快速创建临时对象来存储数据。使用匿名对象可以避免编写大量的类定义,适合那些只需要在很短时间内存储数据的情况。 获取匿名对象属性值的方法 方法一:使用dynamic类型获取属性值 使用dynamic关键字可以通过属性名称直接获…

    C# 2023年6月1日
    00
  • 详解如何通过C#/VB.NET调整PDF文档页边距

    请参考以下完整攻略: 1. 安装依赖库 要使用C#/VB.NET调整PDF文档页边距,我们需要使用一个PDF库来操作PDF文档。这里我们使用iTextSharp库来进行操作。在Visual Studio中打开项目,右键单击项目,然后选择“管理NuGet包”。在NuGet包管理器中搜索“iTextSharp”,然后离线安装。 2. 加载PDF文档 使用iTex…

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