.NET Compact Framework 1.x 下进行UDP通信

来源:互联网 发布:yy网络男主播赵哈哈 编辑:程序博客网 时间:2024/05/07 20:55

上篇中,我介绍了如何进行本地Socket通信,那只是粗略的介绍了一下Smartphone和PC端IP的获取。我个人认为Smartphone/PC这种虚拟网卡连接结构,实现本地的通讯,UDP是个不错的选择 。UDP是面向无连接的,对于SmartPhone来说所占的资源开销会少得多,而且要比TCP稳定的多。当然这需要我们自己在通讯协议上进行控制,不过SmartPhone/PC这种结构,网络环境相对比较简单,也无须做过多控制。

在SmartPhone/PC结构中,我觉得比较适合与胖客户端和胖服务端,姑且不论我的提法是否正确,我想要说的是,我们在做SmartPhone/PC的网络通讯的时候,可以采取相对简单的协议,真正的业务处理要交由SmartPhone或者PC。

这里,我只给出一个经过我修改UDP Server,UDP中其实无所谓Server与Client,Server也可以作为Client来看待,当然UDP Server用来做UDP Client也是非常合理。

UDPCommon.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;

namespace UDPCS
{
    class UDPCommon
    {
        public delegate void ReceivedHandler(object o, ReceivedEventArgs e);
        public delegate void ReceivedBufferHandler(object o, ReceivedBufferEventArgs e);

        private Thread m_UDPThread;         //UDP接收线程
        private string m_CurrentIP;         //本地IP
        private int m_CurrentPort;          //本地端口
        private IPEndPoint m_LocalEndPoint; //本地IP和端口容器
        private Socket m_Socket;            //UDP Socket

        private int m_iState;

        public UDPCommon()
        {

        }

        public event ReceivedHandler OnReceivedData;
        public event ReceivedBufferHandler OnReceivedBuffer;

        public int StartListen(string IP, int Port)
        {
            m_CurrentIP = IP;
            m_CurrentPort = Port;

            //尝试启动接收线程
            try
            {
                m_UDPThread = new Thread(new ThreadStart(ReceiveLoop));
                m_UDPThread.Name = "RecieveThread";
                m_UDPThread.Start();
            }
            catch (Exception e)
            {
                return UDPConstants.UDP_LISTEN_FAIL;
            }
            return UDPConstants.UDP_LISTEN_SUCESS;
        }

        public int StopListen()
        {
            if (m_iState != UDPConstants.UPD_STATE_LISTENING)
            {
                return UDPConstants.UDP_LISTEN_FAIL;
            }

            m_iState = UDPConstants.UDP_STATE_CLOSING;

            m_Socket.Shutdown(SocketShutdown.Both);
            m_Socket.Close();

            m_UDPThread.Abort();
            m_UDPThread = null;

            return UDPConstants.UDP_OK;
        }

        private void ReceiveLoop()
        {
            if (m_CurrentIP == "")
                m_LocalEndPoint = new IPEndPoint(IPAddress.Any, m_CurrentPort);
            else
                m_LocalEndPoint = new IPEndPoint(IPAddress.Parse(m_CurrentIP), m_CurrentPort);

            try
            {
                m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                m_Socket.Bind(m_LocalEndPoint);

                m_iState = UDPConstants.UPD_STATE_LISTENING;

                while (true)
                {
                    try
                    {
                        //Make space to store the data from the socket
                        Byte[] received = new Byte[UDPConstants.MAX_BUFFER_LEN];

                        //Create an end point, just give it temporary values
                        EndPoint remoteEP = new IPEndPoint(m_LocalEndPoint.Address, m_LocalEndPoint.Port);

                        //Read bytes from the socket
                        int bytesReceived = m_Socket.ReceiveFrom(received, ref remoteEP);
                        string str_received = UnicodeEncoding.ASCII.GetString(received, 0, bytesReceived);
                        IPEndPoint remoteIPEP = (IPEndPoint)remoteEP;
                        if(OnReceivedData != null)
                        {
                            OnReceivedData(null, new ReceivedEventArgs((IPEndPoint)remoteEP, str_received));
                        }
                        if (OnReceivedBuffer != null)
                        {
                            OnReceivedBuffer(null, new ReceivedBufferEventArgs((IPEndPoint)remoteEP, received, bytesReceived));
                        }
                    }
                    catch
                    {

                    }
                }
            }
            catch
            {

            }
        }

        public int SendBuffer(string IP, int Port, byte[] buffer)
        {
            if (m_iState != UDPConstants.UPD_STATE_LISTENING)
                return UDPConstants.UDP_SEND_FAIL;

            try
            {

                EndPoint remoteEP = new IPEndPoint(IPAddress.Parse(IP), Port);
                m_Socket.SendTo(buffer, remoteEP);
            }
            catch (SocketException se)
            {
                return UDPConstants.UDP_SEND_FAIL;
            }
            catch (Exception e)
            {
                return UDPConstants.UDP_SEND_FAIL;
            }
            return UDPConstants.UDP_SEND_SUCESS;
        }

        public int SendData(string IP, int Port, string Data)
        {
            if (m_iState != UDPConstants.UPD_STATE_LISTENING)
                return UDPConstants.UDP_SEND_FAIL;

            try
            {
                //byte[] databytes = Encoding.UTF8.GetBytes(Data);
                byte[] databytes = UnicodeEncoding.ASCII.GetBytes(Data);

                EndPoint remoteEP = new IPEndPoint(IPAddress.Parse(IP), Port);
                m_Socket.SendTo(databytes, remoteEP);
            }
            catch (SocketException se)
            {
                return UDPConstants.UDP_SEND_FAIL;
            }
            catch (Exception e)
            {
                return UDPConstants.UDP_SEND_FAIL;
            }
            return UDPConstants.UDP_SEND_SUCESS;
        }

        public class ReceivedEventArgs : EventArgs
        {
            public readonly IPEndPoint RemoteHost;
            public readonly string Data;

            public ReceivedEventArgs(IPEndPoint Remote, string ReceivedData)
            {
                Data = ReceivedData;
                RemoteHost = Remote;
            }
        }

        public class ReceivedBufferEventArgs : EventArgs
        {
            public readonly IPEndPoint RemoteHost;
            public readonly byte[] Data;
            public readonly int Size;

            public ReceivedBufferEventArgs(IPEndPoint Remote, byte[] ReceivedData, int DataSize)
            {
                Data = ReceivedData;
                RemoteHost = Remote;
                Size = DataSize;
            }
        }
    }
}

UDPConstants.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace UDPCS
{
    class UDPConstants
    {
        public static int UDP_LISTEN_SUCESS             = 1;
        public static int UDP_LISTEN_FAIL               = -1;
        public static int UPD_STATE_LISTENING           = 2;
        public static int UDP_STATE_CLOSING             = 3;
        public static int UDP_OK                        = 4;
        public static int UDP_SEND_FAIL                 = 5;
        public static int UDP_SEND_SUCESS               = 6;

       //我设置的缓冲比较大,但是8K的开销还是可以负担的

        public static int MAX_BUFFER_LEN                = 1024 * 8; 
    }
}

 

Good Luck!

注:部分代码出自CodeProject的Demo!

原创粉丝点击