讲udp应用之前,我先简单说一下udp与tcp之间的区别。
udp与tcp之间的区别
udp |
tcp |
容易丢包 |
保证数据正确性 |
程序结构简单 |
程序结构复杂 |
流模式 |
数据模式 |
对系统资源要求少 |
对系统资源要求多 |
无连接 |
连接 |
数据是无序的 |
数据有序 |
接下来简单讲一下udp收发包的应用(点对点的应用):
一,发包:
1,首先创建一个网络端点:
IPEndPoint ipep = new IPEndPoint(IPAdress.Parse(ip), 9050);
此类有两个参数:第一个是接收端的IP,第二个是接收端的端口号。
2,接下来创建一个UdpClient对象:
UdpClient udpClient=new UdpClient();
3,准备发送:
发送时候有同步和异步两种方式,两种方式都有多种重载方法,下面每个讲其中一种,具体用哪种,看各自的需要。
a.异步发送:
方法:BeginSend(...);
参数:
BeginSend
(
byte[] datagram,//要发送的数据字节数组
int bytes,//要发送的数据的长度
AsyncCallback requestCallback,//发送完成后的回调函数
object state//用户自己定义发送完成成后的返回状态,在requestCallback有体现。
);
EndSend
(
IAsyncResult result//BeginSend返回的IAsyncResult s
)
使用:
public void SendData(string ip,int port,object data) { IPEndPoint ipep = new IPEndPoint(IPAdress.Parse(ip), port); UdpClient udpClient=new UdpClient(); udpClient.BeginSend(data,data.Length,ipep,SendComplete,new AsyncCallbackArg(ip,udpClient)); }
///<summary>
///发送完成后的回调函数
///</summary>
///<param name="param"></param> private void sendComplete(IAsyncResult param) { AsyncCallbackArg arg=param.AsyncState as AsyncCallbackArg;//param.AsyncState 对应的就是BeginSend的最后一个参数state using(UdpClient client=(UdpClient)param.AsyncState) {
try
{ client.EndSend(param);//这句话必须得写,BeginSend()和EndSend()是成对出现的
}
catch(Exception ex)
{
....
}
}
//自己定义的返回状态参数类型 private struct AsyncCallbackArg { private UdpClient udpClient; private string ipAddress; public AsyncCallbackArg(string ip,string client) { udpClient=client; ipAddress=ip; } }
b.同步发送:
方法:Send(...);
参数:
Send
(
byte[] datagram,//要发送的数据字节数组
int bytes,//要发送的数据的长度
IPEndPoint endPoint//接收端的ip和端口对象
);
使用:
public void SendData(string ip,int port,object data) { IPEndPoint ipep = new IPEndPoint(IPAdress.Parse(ip), port); UdpClient udpClient=new UdpClient(); udpClient.Send(data,data.Length,ipep); }
二,收包
1,首先需要给本地接收端指定一个端口号port。发送端发送数据之前需要传入的是接收端的ip和端口号。
2,接下来创建一个UdpClient对象:
UdpClient udpClient=new UdpClient(port);
3,准备接收:
接收时候同样也有有同步和异步两种方式。
a.异步接收:
方法:BeginReceive(...);
参数:
BeginReceive
(
AsyncCallback requestCallback,//接收完后的回调函数
object state//用户自己定义接收完成成后的返回状态,在requestCallback有体现。
);
EndReceive
{
IAsyncResult asyncResult,//BeginReceive返回的IAsyncResult
ref IPEndPoint remoteEp//获取的发送方的相关信息
}
使用:
private int m_Port;
private bool m_IsReceive;
private UdpClient m_ReceiveUdpClient;
private Thread m_ReceiveThread;
public void StartReceiveData(int port) {
m_IsReceive=true; m_Port=port; m_ReceiveThread=new Thread(); m_ReceiveThread.IsBackground=true; m_ReceiveThreads.start(); }
private void Receive() { m_ReceiveUdpClient=new UdpClient(m_Port); byte[] data; while(m_IsReceive) { if(m_ReceiveUdpClient.Client==null) { break; } if(m_ReceiveUdpClient.Client.Poll(-1,SelectMode.Selectread)) { break; }
try{ m_ReceiveUdpClient.BeginReceive(new AsyncCallBack(ReceiveComplete),m_ReceiveUdpClient); }catch(Exception ex){ .....} } }
private void ReceiveComplete(IAsyncResult param) { UDPClient client=param.AsyncState as UDPClient ;//对应的就是BeginSend的最后一个参数state try { IPEndPoint ipep = new IPEndPoint(IPAdress.Any,m_Port); byte[] datas=client.EndReceive(param,ref ipep);//接受到的数据 } catch(Exception ex) { .... } }
b.同步接收:
方法:Receive(...);
参数:
Receive
(
ref IPEndPoint endPoint////获取的发送方的相关信息s
);
使用:
private int m_Port; public void StartReceiveData(int port) { m_Port=port; m_ReceiveThread=new Thread(); m_ReceiveThread.IsBackground=true; m_ReceiveThread.start(); }
private void Receive() { m_ReceiveUdpClient=new UdpClient(m_Port); byte[] data; while(m_IsReceive) { if( m_ReceiveUdpClient.Client==null) { break; } if( m_ReceiveUdpClient.Client.Poll(-1,SelectMode.Selectread)) { break; } try{ IPEndPoint ip=new IPEndPoint(); data= m_ReceiveUdpClient.Receive(ref ip);
}catch(Exception ex){ .....} } }
停止接收:
private void StopReceive() { m_IsReceive=false; if(m_ReceiveUdpClient!=null) { m_ReceiveUdpClient.Close(); } if(m_ReceiveThread!=null &&m_ReceiveThread.ThreadState==ThreadState.Running) { m_ReceiveThread.Abort(); } }
|
请发表评论