C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > WinForm Socket异步通讯

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

作者:小码编匠

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异步通讯的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文