C# WinForm实现Socket异步通讯的步骤详解

 更新时间:2025年07月30日 10:34:31   作者:小码编匠  
Socket通讯是网络编程中非常基础且重要的一部分,它为应用程序提供了基于TCP/IP协议进行数据传输的能力,本文将详细介绍如何在C#的WinForm应用程序中实现Socket的异步通讯,希望能为有需要的开发提供一些参考,需要的朋友可以参考下

前言

在工作中,我们常常会用到各种知识点,但有时用完后就容易遗忘。为了更好地记录和回顾这些知识,尝试用笔记的形式将其整理下来,以备后用。

Socket通讯是网络编程中非常基础且重要的一部分,它为应用程序提供了基于TCP/IP协议进行数据传输的能力。

本文将详细介绍如何在C#的WinForm应用程序中实现Socket的异步通讯,希望能为有需要的开发提供一些参考。

Socket 通讯

Socket(套接字)是基于TCP/IP通讯方式封装好的类。在使用Socket进行编程时,需要添加相关的服务引用,以下是在C#项目中需要引入的命名空间:

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

窗体页面搭建

在WinForm窗体中,我们搭建一个简单的界面,将窗体分为上下两个区域,上面作为服务器区,下面作为客户端区。

这样可以在一个界面中同时展示服务器和客户端的操作。

服务器类实现

1、声明变量

首先,我们需要声明一些必要的变量,包括IP地址、端口号、网络端点、侦听连接套接字、通讯套接字以及数据缓冲区等。

同时,定义一个委托用于显示消息。

string ip;//IP地址
string port;//端口号
IPEndPoint endPoint;//网络端点
Socket socServer;//侦听连接套接字
Socket socClient;//通讯套接字
byte[] dataReceived = new byte[50000];

public delegate void delegateDisplayMsg(string type,string msg);
public delegateDisplayMsg OnDisplay;

public SocketServer()
{
    socServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}

2、侦听连接函数

该函数用于启动服务器的侦听功能,绑定指定的IP地址和端口号,并开始接受客户端的连接请求。

public void StartListen(string ip,string port)
{
    this.ip = ip;
    this.port = port;
    endPoint = new IPEndPoint(IPAddress.Parse(this.ip), int.Parse(port));
    socServer.Bind(endPoint);
    socServer.Listen(0);
    socServer.BeginAccept(new AsyncCallback(OnClientConnect), null);
    ShowMsg("Wait Connect");
}

3、接受数据函数

当有客户端连接时,OnClientConnect方法会被调用,它接受客户端的连接并调用WaitForData方法等待接收数据。

OnDataReceived方法用于处理接收到的数据,将字节数组转换为字符串并显示。

public void OnClientConnect(IAsyncResult asyn)
{
    socClient = socServer.EndAccept(asyn);
    WaitForData();
    ShowMsg("Client Connected  " + socClient.RemoteEndPoint.ToString());
}
public void WaitForData()
{
    if (socClient != null)
        socClient.BeginReceive(dataReceived, 0, dataReceived.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), null);
}
public void OnDataReceived(IAsyncResult asyn)
{
    int dataLength = socClient.EndReceive(asyn);
    byte[] chars = new byte[dataLength];
    Buffer.BlockCopy(dataReceived, 0, chars, 0, dataLength);
    string msg = Encoding.ASCII.GetString(chars);
    ShowMsg("<=" + msg);
    WaitForData();
}

4、发送数据函数

SendMsg方法用于向客户端发送数据,将字符串转换为字节数组后通过套接字发送。

public void SendMsg(string msg)
{
    byte[] data = Encoding.Default.GetBytes(msg);
    socClient.Send(data);
    ShowMsg("=>" + msg);
}

客户端类实现

1、声明变量

客户端类也需要声明类似的变量,用于存储服务器信息、通讯套接字以及数据缓冲区等。

string ip;//IP地址
string port;//端口号
IPEndPoint endPoint;//网络端点
Socket socClient;//通讯套接字
byte[] dataReceived = new byte[50000];//数据Buffer

public delegate void delegateDisplayMsg(string type,string msg);
public delegateDisplayMsg OnDisplay;

public SocketClient()
{
    socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}

2、连接服务器函数

Connect方法用于发起与服务器的连接请求。

public void Connect(string ip, string port)
{
    this.ip = ip;
    this.port = port;
    endPoint = new IPEndPoint(IPAddress.Parse(this.ip), int.Parse(port));
    socClient.BeginConnect(endPoint, new AsyncCallback(OnToConnected), null);
}

3、接受数据函数

当连接成功时,OnToConnected方法会被调用,它调用WaitForData方法等待接收数据。OnDataReceived方法的处理逻辑与服务器端类似。

public void OnToConnected(IAsyncResult asyn)
{
    socClient.EndConnect(asyn);
    WaitForData();
    ShowMsg("Connect Success");
}
public void WaitForData()
{
    if (socClient != null)
        socClient.BeginReceive(dataReceived, 0, dataReceived.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), null);
}
public void OnDataReceived(IAsyncResult asyn)
{
    int dataLenth = socClient.EndReceive(asyn);
    byte[] chars = new byte[dataLenth];
    Buffer.BlockCopy(dataReceived, 0, chars, 0, dataLenth);
    string msg = Encoding.ASCII.GetString(chars);
    ShowMsg("<=" + msg);
    WaitForData();
}

4、发送数据函数

与服务器端的SendMsg方法类似,客户端的SendMsg方法也用于向服务器发送数据。

public void SendMsg(string msg)
{
    byte[] data = Encoding.Default.GetBytes(msg);
    socClient.Send(data);
    ShowMsg("=>" + msg);
}

实例化与事件绑定

在窗体类中,我们需要实例化服务器类和客户端类,并将它们的消息显示委托绑定到窗体的消息显示方法上。

public void Init()
{
     Server = new SocketServer();
     Client = new SocketClient();
     Server.OnDisplay += ShowMsg;
     Client.OnDisplay += ShowMsg;
}

按钮点击事件处理

为窗体上的按钮添加点击事件处理函数,实现服务器的启动侦听、客户端的连接以及数据的发送功能。

private void btn_StartListen_Click(object sender, EventArgs e)
{
    Server.StartListen(txt_serverIP.Text.ToString(), txt_serverPort.Text.ToString());
    btn_StartListen.BackColor = Color.LimeGreen;
}

private void btn_Connect_Click(object sender, EventArgs e)
{
    Client.Connect(txt_clientIP.Text.ToString(), txt_clientPort.Text.ToString());
}

private void btn_serverSend_Click(object sender, EventArgs e)
{
    Button b = (Button)sender;
    bool isServer = b.Name.Contains("server");
    if (isServer)
        Server.SendMsg(txt_serverMsg.Text.ToString());
    else
        Client.SendMsg(txt_clientMsg.Text.ToString());
}

示例效果

总结

通过以上步骤,成功在C#的WinForm应用程序中实现了一个简单的Socket异步通讯模型。这个模型包含了服务器端和客户端的基本功能,如侦听连接、接受数据和发送数据等。

然而,在实际应用中,还需要考虑更多的因素,例如通讯异常的处理、通讯协议的设计以及多个客户端同时通讯的情况等。希望本文的示例能为初学者提供一个良好的起点,也欢迎大家提出宝贵的意见和建议。

以上就是C# WinForm实现Socket异步通讯的步骤详解的详细内容,更多关于WinForm Socket异步通讯的资料请关注脚本之家其它相关文章!

相关文章

  • C#中实现任意List的全组合算法代码

    C#中实现任意List的全组合算法代码

    这篇文章主要是介绍了.net C# 实现任意List的全组合算法实现代码,需要的朋友可以参考下
    2013-05-05
  • C#如何打开选择文件对话框和选择目录对话框

    C#如何打开选择文件对话框和选择目录对话框

    这篇文章主要介绍了C#如何打开选择文件对话框和选择目录对话框问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 基于WPF自定义分页控件的示例代码

    基于WPF自定义分页控件的示例代码

    在桌面应用程序开发中,特别是使用WPF框架时,数据展示和用户交互的优化至关重要,本文将介绍两种不同的分页控件的实现方式,有需要的可以了解下
    2025-07-07
  • Visual Studio 中自定义代码片段的方法

    Visual Studio 中自定义代码片段的方法

    这篇文章主要介绍了Visual Studio 中自定义代码片段的方法,本文分步骤通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C#图表算法之最短路径

    C#图表算法之最短路径

    本文详细讲解了C#图表算法之最短路径,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • c# 向MySQL添加数据的两种方法

    c# 向MySQL添加数据的两种方法

    这篇文章主要介绍了c# 向MySQL添加数据的两种方法,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • C#中foreach循环对比for循环的优势和劣势

    C#中foreach循环对比for循环的优势和劣势

    循环语句是编程的基本语句,在C#中除了沿用C语言的循环语句外,还提供了foreach语句来实现循环,下面这篇文章主要给大家介绍了关于C#中foreach循环对比for循环的优势和劣势,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09
  • 聊聊C#中的Mixin的具体用法

    聊聊C#中的Mixin的具体用法

    本文主要介绍了C#中的Mixin的具体用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • C#运算符大全_各种运算符号的概述及作用

    C#运算符大全_各种运算符号的概述及作用

    以下是对C#中各种运算符号的说明及作用进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • C#利用Windows自带gdi32.dll实现抓取屏幕功能实例

    C#利用Windows自带gdi32.dll实现抓取屏幕功能实例

    这篇文章主要介绍了C#利用Windows自带gdi32.dll实现抓取屏幕功能,是C#程序设计中常见的一个重要技巧,需要的朋友可以参考下
    2014-08-08

最新评论