c#实现简单控制台udp异步通信程序示例
实现客户端发送请求,服务器端响应机制
udp客户端代码
using system;
using system.text;
using system.net;
using system.net.sockets;
namespace client
{
class program
{
//客户端 socket对象
private static socket clientsocket;
//服务器端 终点
private static endpoint epserver;
//接收数据的字符数组
private static byte[] receivedata;
public static void main(string[] args)
{
//客户端socket对象实例化
clientsocket = new socket(addressfamily.internetwork, sockettype.dgram, protocoltype.udp);
//设置服务器端ip地址和对应端口
ipendpoint server = new ipendpoint(ipaddress.parse("192.168.1.165"), 11000);
//实例化服务器端 终点
epserver = (endpoint)server;
string msg; //要发送的消息
byte[] senddata; //要发送的字符串
while (true) {
msg = console.readline(); //输入要发送的消息
if (msg == "exit") break; //当输入“exit”时,退出客户端程序
//将消息通过ascii编码转换为字符数组,
//如果要发送汉字或其他特殊符号,可以采用utf-8
senddata = encoding.ascii.getbytes(msg);
//开始异步发送消息
//参数:senddata 要发送的数据
//参数:0: 要发送数据的起始位置
//参数:senddata.length: 要发送数据的字节数
//参数:socketflags.none: 按位组合方式
//参数:epserver: 接收方设备(包含ip和端口)
//参数:new asynccallback(senddata): 委托
//参数:null: 请求的状态信息
clientsocket.beginsendto(senddata, 0, senddata.length, socketflags.none,
epserver, new asynccallback(senddata), null);
//实例化接收数据的字符数组
//若在声明时已经初始化,此处依然要进行重新初始化
//当上次接收的数据长度大于本次,则该数组里包含上次接收的残留数据
//比如:上次接收“你个小逗逼”。本次接收“开玩笑”。
//则数组中的数据为:“开玩笑逗逼”。
receivedata = new byte[1024];
//开始异步接收消息
//参数部分与异步发送部分对应,基本一致
clientsocket.beginreceivefrom(receivedata, 0, receivedata.length, socketflags.none,
ref epserver, new asynccallback(receivedata), null);
}
}
//异步发送消息的委托函数
private static void senddata(iasyncresult iar)
{
//完成异步发送
clientsocket.endsend(iar);
}
//异步接收消息的委托函数
private static void receivedata(iasyncresult iar)
{
//完成异步接收 recv 表示接收到的字节数
int recv = clientsocket.endreceive(iar);
//将接收到的数据打印出来
console.writeline("server: " + encoding.ascii.getstring(receivedata, 0, recv));
}
}
}
udp服务器端代码
using system;
using system.text;
using system.net;
using system.net.sockets;
namespace server
{
class asyncudpserver
{
//服务器端socket对象
private static socket serversocket;
//接收数据的字符数组
private static byte[] receivedata = new byte[1024];
public static void main(string[] args)
{
//实例化服务器端socket对象
serversocket = new socket(addressfamily.internetwork, sockettype.dgram, protocoltype.udp);
//服务器端的ip和端口,ipaddress.any实际是:0.0.0.0,表示任意,基本上表示本机ip
ipendpoint server = new ipendpoint(ipaddress.any, 11000);
//socket对象跟服务器端的ip和端口绑定
serversocket.bind(server);
//客户端的ip和端口,端口 0 表示任意端口
ipendpoint clients = new ipendpoint(ipaddress.any, 0);
//实例化客户端 终点
endpoint epsender = (endpoint)clients;
//开始异步接收消息 接收后,epsender存储的是发送方的ip和端口
serversocket.beginreceivefrom(receivedata, 0, receivedata.length, socketflags.none,
ref epsender, new asynccallback(receivedata), epsender);
console.writeline("listening...");
console.readline();
}
private static void senddata(iasyncresult iar)
{
serversocket.endsend(iar);
}
private static void receivedata(iasyncresult iar)
{
//客户端的ip和端口,端口 0 表示任意端口
ipendpoint client = new ipendpoint(ipaddress.any, 0);
//实例化客户端 终点
endpoint epsender = (endpoint)client;
//结束异步接收消息 recv 表示接收到的字符数
int recv = serversocket.endreceivefrom(iar, ref epsender);
//将接收到的数据打印出来,发送方采用什么编码方式,此处就采用什么编码方式 转换成字符串
console.writeline("client:" + encoding.ascii.getstring(receivedata, 0, recv));
//定义要发送回客户端的消息,采用ascii编码,
//如果要发送汉字或其他特殊符号,可以采用utf-8
byte[] senddata = encoding.ascii.getbytes("hello");
//开始异步发送消息 epsender是上次接收消息时的客户端ip和端口信息
serversocket.beginsendto(senddata, 0, senddata.length, socketflags.none,
epsender, new asynccallback(senddata), epsender);
//重新实例化接收数据字节数组
receivedata = new byte[1024];
//开始异步接收消息,此处的委托函数是这个函数本身,递归
serversocket.beginreceivefrom(receivedata, 0, receivedata.length, socketflags.none,
ref epsender, new asynccallback(receivedata), epsender);
}
}
}