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