前言
在工作中,我们常常会用到各种知识点,但有时用完后就容易遗忘。为了更好地记录和回顾这些知识,尝试用笔记的形式将其整理下来,以备后用。
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异步通讯的资料请关注代码网其它相关文章!
发表评论