C# UDP接收不同端口的数据报文

来源:互联网 发布:udp 17端口 编辑:程序博客网 时间:2024/05/22 05:13

在unity中使用UDP进行数据的交互,建立C/S模式,两个客户端和一个服务端。两个客户端使用不同的端口往服务端发送数据,服务端根据收到的数据进行处理和判断,控制服务端的显示。

说明:两个客户端连接的是Kinect V2,需要将检测到的人体的数据信息发送到服务端进行系统数据的整体显示。指定的消息协议是ClientID|index|PosLeft|Left_S|PosRight|Right_S|ACTION| ClientID|index|PosLeft|Left_S|PosRight|Right_S|ACTION| ...

这是客户端根据检测到人体的数量向服务端发送的数据格式。

服务端:使用两个线程用于接收两个客户端的数据,将收到的数据添加到Queue中。在需要显示数据的Update中从Queue中取出数据进行处理控制。

这里服务端的接收数据脚本直接上代码:

using UnityEngine;using System.Collections;//引入库using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Collections.Generic;public class UdpHelpHandler : MonoBehaviour {//以下默认都是私有的成员Socket socket,socket2; //目标socketEndPoint clientEnd; //客户端IPEndPoint ipEnd,ipEnd2; //侦听端口string recvStr,recvStr2; //接收的字符串string sendStr; //发送的字符串byte[] recvData=new byte[1024]; //接收的数据,必须为字节byte[] recvData2=new byte[1024]; //接收的数据,必须为字节byte[] sendData=new byte[1024]; //发送的数据,必须为字节int recvLen,recvLen2; //接收的数据长度Thread connectThread,connectThread2; //连接线程    int[] WaveCounts = new int[2];    int[] TPoseCounts = new int[2];public Queue<string> queueClient1 = new Queue<string>();public Queue<string> queueClient2 = new Queue<string>();private System.Object thisLock = new System.Object ();//初始化publicvoid InitSocket(){//定义侦听端口,侦听任何IPipEnd=new IPEndPoint(IPAddress.Any,2000);//定义套接字类型,在主线程中定义socket=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);//服务端需要绑定iptry{socket.Bind(ipEnd);}catch (System.Exception ex) {socket.Close ();Debug.LogError(ex.Message + "\n" + ex.StackTrace);}//定义侦听端口,侦听任何IPipEnd2=new IPEndPoint(IPAddress.Any,3000);//定义套接字类型,在主线程中定义socket2=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);//服务端需要绑定iptry{socket2.Bind(ipEnd2);}catch (System.Exception ex) {socket2.Close ();Debug.LogError(ex.Message + "\n" + ex.StackTrace);}//定义客户端IPEndPoint sender=new IPEndPoint(IPAddress.Any,0);clientEnd=(EndPoint)sender;print("waiting for UDP dgram");//开启一个线程连接,必须的,否则主线程卡死connectThread=new Thread(new ThreadStart(SocketReceive));connectThread.Start();//开启一个线程连接,必须的,否则主线程卡死connectThread2=new Thread(new ThreadStart(SocketReceive2));connectThread2.Start();}void SocketSend(string sendStr){//清空发送缓存sendData=new byte[1024];//数据类型转换sendData=Encoding.ASCII.GetBytes(sendStr);//发送给指定客户端socket.SendTo(sendData,sendData.Length,SocketFlags.None,clientEnd);}//服务器接收void SocketReceive(){//进入接收循环while(true){//对data清零recvData=new byte[1024];//获取客户端,获取客户端数据,用引用给客户端赋值recvLen=socket.ReceiveFrom(recvData,ref clientEnd);//输出接收到的数据recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);            char[] msgDelim = { '|' };            string[] asMessages = recvStr.Split(msgDelim);  if (asMessages.Length > 7) {queueClient1.Enqueue (recvStr);if (int.Parse (asMessages [0]) == 2) {if (int.Parse (asMessages [6]) == 6) { //wave                      SetWaveCountsClient1 (2);}                    } else if (int.Parse (asMessages [0]) == 3) {if (int.Parse (asMessages [6]) == 6) { //waveSetWaveCountsClient2 (3);}                    }}        }}//服务器接收void SocketReceive2(){//进入接收循环while(true){//对data清零recvData2=new byte[1024];//获取客户端,获取客户端数据,用引用给客户端赋值recvLen2=socket2.ReceiveFrom(recvData2,ref clientEnd);//输出接收到的数据recvStr2=Encoding.ASCII.GetString(recvData2,0,recvLen2);char[] msgDelim = { '|' };string[] asMessages = recvStr2.Split(msgDelim);if (asMessages.Length > 7){queueClient2.Enqueue (recvStr2);if (int.Parse(asMessages[0]) == 2){if(int.Parse(asMessages[6]) == 6) //wave{SetWaveCountsClient1(2);}}else if (int.Parse(asMessages[0]) == 3){if (int.Parse(asMessages[6]) == 6) //wave{SetWaveCountsClient2(3);}}}}}    public void SetWaveCountsClient1(int index)    {        if (index == 2)        {            WaveCounts[0]++;        }    }public void SetWaveCountsClient2(int index){        if (index == 3)WaveCounts[1]++;}    public void SetTposeCounts(int index)    {        if (index == 2)            TPoseCounts[0]++;        else if (index == 3)            TPoseCounts[1]++;    }    public int GetWaveCounts(int index)    {        int ret = 0;        if (index == 2)        {            if (WaveCounts[0] > 0)                ret = WaveCounts[0]--;        }        else if (index == 3)        {            if (WaveCounts[1] > 0)                ret = WaveCounts[1]--;        }        return ret;    }    public int GetTposeCounts(int index)    {        int ret = 0;        if (index == 2)        {            if (TPoseCounts[0] > 0)                ret = TPoseCounts[0]--;        }        else if (index == 3)        {            if (TPoseCounts[1] > 0)                ret = TPoseCounts[1]--;        }        return ret;    }    //返回接收到的字符串      public string GetRecvStr(){string returnStr="";//加锁防止字符串被改  if (queueClient1.Count > 0) {lock (/*thisLock*/queueClient1) {//returnStr=recvStr;returnStr = queueClient1.Dequeue ();}}return returnStr;} //返回接收到的字符串  public void setRecvStr(){//加锁防止字符串被改  lock(thisLock){recvStr = null;}} //返回接收到的字符串  public string GetRecvStr2(){string returnStr="";if (queueClient2.Count > 0) {lock (/*thisLock*/queueClient2) {//returnStr=recvStr;returnStr = queueClient2.Dequeue ();}}return returnStr;} //返回接收到的字符串  public void setRecvStr2(){//加锁防止字符串被改  lock(thisLock){recvStr2 = null;}} //连接关闭publicvoid SocketQuit(){//关闭线程if(connectThread!=null){connectThread.Interrupt();connectThread.Abort();}if(connectThread2!=null){connectThread2.Interrupt();connectThread2.Abort();}//最后关闭socketif(socket!=null)socket.Close();//最后关闭socketif(socket2!=null)socket2.Close();print("disconnect");}}


客户端代码如下:

using UnityEngine;using System.Collections;//引入库using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Xml;//客户端public class UdpHelpHandler : MonoBehaviour {//以下默认都是私有的成员Socket socket; //目标socketEndPoint serverEnd; //服务端IPEndPoint ipEnd; //服务端端口string recvStr; //接收的字符串string sendStr; //发送的字符串byte[] recvData=new byte[1024]; //接收的数据,必须为字节byte[] sendData=new byte[1024]; //发送的数据,必须为字节int recvLen; //接收的数据长度Thread connectThread; //连接线程public bool isClient =true;//初始化public void InitSocket(string ipHostString,int port){//定义连接的服务器ip和端口,可以是本机ip,局域网,互联网ipEnd=new IPEndPoint(IPAddress.Parse(ipHostString),port);//定义套接字类型,在主线程中定义socket=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);//定义服务端IPEndPoint sender=new IPEndPoint(IPAddress.Any,0);serverEnd=(EndPoint)sender;print("waiting for sending UDP dgram....");//建立初始连接,这句非常重要,第一次连接初始化了serverEnd后面才能收到消息//开启一个线程连接,必须的,否则主线程卡死connectThread=new Thread(new ThreadStart(SocketReceive));connectThread.Start();}public void SocketSend(string sendStr){//清空发送缓存sendData=new byte[1024];//数据类型转换sendData=Encoding.ASCII.GetBytes(sendStr);//发送给指定服务端socket.SendTo(sendData,sendData.Length,SocketFlags.None,ipEnd);}//服务器接收void SocketReceive(){//进入接收循环while(true){//print("recv thread");//对data清零recvData=new byte[1024];//获取客户端,获取服务端端数据,用引用给服务端赋值,实际上服务端已经定义好并不需要赋值recvLen=socket.ReceiveFrom(recvData,ref serverEnd);//print("message from: "+serverEnd.ToString()); //打印服务端信息//输出接收到的数据recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);//print(recvStr);}}//连接关闭public void SocketQuit(){//关闭线程if(connectThread!=null){connectThread.Interrupt();connectThread.Abort();}//最后关闭socketif(socket!=null)socket.Close();}}





原创粉丝点击