using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace MySockets
{
public class UdpTransciverEventArgs : EventArgs
{
public byte[] Data;
public UdpTransciverEventArgs(byte[] Data)
{
this.Data = Data;
}
}
public class UdpTransceiver
{
private UdpClient sender;
private IPEndPoint remoteEndPoint;
private int maxOnceSend;
private int offset;
private int delayMillis;
private byte[] dataToSend;
private bool isSending;
private bool isReceiving;
private void OnReceived(object sender, UdpTransciverEventArgs e)
{
if (UdpReceiveDetected != null)
UdpReceiveDetected(sender, e);
}
private void ReceiveOnce(IAsyncResult ia)
{
UdpClient client = ia.AsyncState as UdpClient;
byte[] data = client.EndReceive(ia, ref localEndPoint);
if(isReceiving)
OnReceived(receiver, new UdpTransciverEventArgs(data));
if (isReceiving)
{
receiver.BeginReceive(ReceiveOnce, receiver);
}
else
{
receiver.Close();
}
}
private void SendOnce(IAsyncResult ia)
{
UdpClient client = ia.AsyncState as UdpClient;
int sent = client.EndSend(ia);
offset += sent;
//下一次还要发送多少字节
int cnt = offset + maxOnceSend >= dataToSend.Length ? (dataToSend.Length - offset - 1) : maxOnceSend;
if (cnt > 0 && (isSending))
{
System.Threading.Thread.Sleep(delayMillis);
//delayMillisecond(delayMillis);
byte[] tmp = new byte[cnt];
Array.Copy(dataToSend, offset, tmp, 0, cnt);
sender.BeginSend(tmp, cnt, remoteEndPoint, SendOnce, sender);
OnSend(client, new UdpTransciverEventArgs(tmp));
}
else
sender.Close();
}
private void EndTmpSender(IAsyncResult ia)
{
UdpClient client = ia.AsyncState as UdpClient;
client.EndSend(ia);
client.Close();
}
private void OnSend(object sender, UdpTransciverEventArgs e)
{
if (UdpSendDetected != null)
UdpSendDetected(sender, e);
}
private void PrepareSend(int maxOnceSend,int delay,byte[] data)
{
offset = 0;
isSending = true;
this.maxOnceSend = maxOnceSend;
this.delayMillis = delay;
this.dataToSend = data;
}
public bool IsSending{get {return isSending;}}
public bool IsReceiving{get {return isReceiving;}}
private UdpClient receiver;
private IPEndPoint localEndPoint;
//Not used.
private void DelayMillisecond(long dlyMilliseconds)
{
long beginTime = DateTime.Now.Ticks;
long dlyTick = dlyMilliseconds * TimeSpan.TicksPerMillisecond;
while (true)
{
long endTime = DateTime.Now.Ticks;
if ((endTime - beginTime) > dlyTick)
break;
}
}
public event EventHandler<UdpTransciverEventArgs> UdpReceiveDetected;
public event EventHandler<UdpTransciverEventArgs> UdpSendDetected;
public void InitSender(string ipAddress, int port)
{
this.sender = new UdpClient();
try
{
IPAddress ip = IPAddress.Parse(ipAddress);
this.remoteEndPoint = new IPEndPoint(ip, port);
}
catch (ArgumentException ar)
{
throw new ArgumentException("Illegal ip address format");
}
}
public void StartSend(byte[] data, int bytes, int delay)
{
PrepareSend(bytes, delay, data);
bytes = bytes > data.Length ? data.Length : (bytes);
sender.BeginSend(data, bytes, remoteEndPoint, SendOnce, sender);
}
//ip:ip地址,为null表示任意ip
//port:端口号
public void InitReceiver(string ip,int port)
{
#region variable verify
if (ip == null)
{
localEndPoint = new IPEndPoint(IPAddress.Any, port);
}
else
{
IPAddress ipAddress;
try
{
ipAddress = IPAddress.Parse(ip);
}
catch (ArgumentException ar)
{
throw new ArgumentException("Illegal ip address format");
}
localEndPoint = new IPEndPoint(ipAddress, port);
}
#endregion
receiver = new UdpClient(localEndPoint);
}
public void StartReceive()
{
isReceiving = true;
receiver.BeginReceive(ReceiveOnce, receiver);
}
public void StopSend()
{
isSending = false;
}
public void StopReceive()
{
this.isReceiving = false;
UdpClient tmp = new UdpClient();
tmp.BeginSend(new byte[] { 0xff }, 1, localEndPoint, EndTmpSender, tmp);
}
}
}
Udp收发,并解决了异步接收时,在收到数据前关闭UdpClient会发生异常退出的问题。
Udp编程
最新推荐文章于 2012-09-02 11:45:46 发布