C# UDP 编程笔记


简单的信息收发

首先启动客户端,然后开启服务端,不然无法接收到服务端发送的消息

服务端代码

/// <summary>
/// 必须先启动客户端,客户端才能接收到消息
/// </summary>
class Program
{

    static void Main(string[] args)
    {

        UdpClient udpClient = new UdpClient(11001);
        try
        {
            udpClient.Connect(IPAddress.Parse("192.168.2.108"), 11000);
            Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody thereA?");

            udpClient.Send(sendBytes, sendBytes.Length);

            udpClient.Close();

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        Console.ReadKey(true);
    }
}

客户端代码

/// <summary>
/// 
/// </summary>
class Program
{
    static void Main(string[] args)
    {

        UdpClient udpClient = new UdpClient(11000);
        try
        {
            IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
            Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
            string returnData = Encoding.ASCII.GetString(receiveBytes);

            Console.WriteLine("This is the message you received " +
                                         returnData.ToString());
            Console.WriteLine("This message was sent from " +
                                        RemoteIpEndPoint.Address.ToString() +
                                        " on their port number " +
                                        RemoteIpEndPoint.Port.ToString());

            udpClient.Close();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }


        Console.ReadKey(true);

    }
}

客户端和服务端写在一起,MSDN 示例

class Program
{
    static void Main(string[] args)
    {

        // This constructor arbitrarily assigns the local port number.
        UdpClient udpClient = new UdpClient(11000);
        try
        {
            udpClient.Connect(IPAddress.Parse("192.168.2.108"), 11000);

            // Sends a message to the host to which you have connected.
            Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody there?");

            udpClient.Send(sendBytes, sendBytes.Length);

            // Sends a message to a different host using optional hostname and port parameters.
            //IPEndPoint RemoteIpEndPoint1 = new IPEndPoint(IPAddress.Parse("192.168.2.255"), 11000);
            //UdpClient udpClientB = new UdpClient();
            //udpClientB.Send(sendBytes, sendBytes.Length, RemoteIpEndPoint1);

            //IPEndPoint object will allow us to read datagrams sent from any source.
            IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);

            // Blocks until a message returns on this socket from a remote host.
            Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
            string returnData = Encoding.ASCII.GetString(receiveBytes);

            // Uses the IPEndPoint object to determine which of these two hosts responded.
            Console.WriteLine("This is the message you received " +
                                         returnData.ToString());
            Console.WriteLine("This message was sent from " +
                                        RemoteIpEndPoint.Address.ToString() +
                                        " on their port number " +
                                        RemoteIpEndPoint.Port.ToString());

            udpClient.Close();
            //udpClientB.Close();

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        Console.ReadKey(true);

    }
}

简单的 UdpClient 一对一通信

使用时,将本机端口号和远程主机端口号对换,生成两个程序,就可有进行通信

class Program
{
    /// <summary>接收用</summary>  
    private static UdpClient receiveUdpClient;
    /// <summary>发送用</summary>  
    private static UdpClient sendUdpClient;
    /// <summary>和本机绑定的端口号</summary>  
    private const int port = 18001;
    /// <summary>和远程绑定的端口号</summary>  
    private const int remotePort = 18002;
    /// <summary>本机IP</summary>  
    static IPAddress ip;
    /// <summary>远程主机IP</summary>  
    static IPAddress remoteIp;

    static void Main(string[] args)
    {
        //获取本机可用IP地址  
        IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
        ip = ips[ips.Length - 1];
        //为了在同一台机器调试,此IP也作为默认远程IP  
        remoteIp = ip;

        //创建一个线程接收远程主机发来的信息  
        Thread myThread = new Thread(ReceiveData);

        //将线程设为后台运行  
        myThread.IsBackground = true;
        myThread.Start();

        string input = string.Empty;

        do
        {
            Console.WriteLine("请输入要发送的信息,输入Q退出\n\n======================\n\n");
            input = Console.ReadLine();
            Thread t = new Thread(SendMessage);//新建发送数据线程  
            t.IsBackground = true;
            t.Start(input);
        } while (!input.Equals("q", StringComparison.OrdinalIgnoreCase));

        Console.WriteLine();


        Console.ReadKey();
    }

    static void ReceiveData()//接收数据  
    {
        IPEndPoint local = new IPEndPoint(ip, port);
        receiveUdpClient = new UdpClient(local);
        IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
        while (true)
        {
            try
            {
                //关闭udpClient时此句会产生异常  
                byte[] receiveBytes = receiveUdpClient.Receive(ref remote);
                string receiveMessage = Encoding.Unicode.GetString(
                    receiveBytes, 0, receiveBytes.Length);
                Console.WriteLine(string.Format("来自{0}:{1}", remote, receiveMessage));
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                break;
            }
        }
    }

    /// <summary>发送数据到远程主机</summary>  
    static void SendMessage(object obj)
    {
        string message = (string)obj;
        sendUdpClient = new UdpClient(0);
        byte[] bytes = System.Text.Encoding.Unicode.GetBytes(message);
        IPEndPoint iep = new IPEndPoint(remoteIp, remotePort);
        try
        {
            sendUdpClient.Send(bytes, bytes.Length, iep);
            Console.WriteLine(     string.Format("向{0}发送:{1}", iep, message));
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }  

}

简单的 UdpClient 一对一异步通信

客户端,即后启动的程序

// 定义 UdpState类
public class UdpState
{
    public UdpClient udpClient = null;
    public IPEndPoint ipEndPoint = null;
    public const int BufferSize = 1024;
    public byte[] buffer = new byte[BufferSize];
    public int counter = 0;
}
// 异步UDP类
public class AsyncUdpClient
{
    public static bool messageSent = false;
    // Receive a message and write it to the console.
    // 定义端口
    private const int listenPort = 1101;
    private const int remotePort = 1100;
    // 定义节点
    private IPEndPoint localEP = null;
    private IPEndPoint remoteEP = null;
    // 定义UDP发送和接收
    private UdpClient udpReceive = null;
    private UdpClient udpSend = null;
    private UdpState udpSendState = null;
    private UdpState udpReceiveState = null;
    private int counter = 0;
    // 异步状态同步
    private ManualResetEvent sendDone = new ManualResetEvent(false);
    private ManualResetEvent receiveDone = new ManualResetEvent(false);
    // 定义套接字
    //private Socket receiveSocket;
    //private Socket sendSocket;

    public AsyncUdpClient()
    {
        // 本机节点
        localEP = new IPEndPoint(IPAddress.Any, listenPort);
        // 远程节点
        IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
        var ip = ips[ips.Length - 1];
        remoteEP = new IPEndPoint(ip, remotePort);
        //remoteEP = new IPEndPoint(Dns.GetHostAddresses(Dns.GetHostName())[0], remotePort);
        // 实例化
        udpReceive = new UdpClient(localEP);
        udpSend = new UdpClient();

        // 分别实例化udpSendState、udpReceiveState
        udpSendState = new UdpState();
        udpSendState.ipEndPoint = remoteEP;
        udpSendState.udpClient = udpSend;

        udpReceiveState = new UdpState();
        udpReceiveState.ipEndPoint = remoteEP;
        udpReceiveState.udpClient = udpReceive;

        //receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        //receiveSocket.Bind(localEP);

        //sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        //sendSocket.Bind(remoteEP);
    }
    // 发送函数
    public void SendMsg()
    {
        udpSend.Connect(remoteEP);

        //Thread t = new Thread(new ThreadStart(ReceiveMessages));
        //t.Start();
        Byte[] sendBytes;
        string message;
        while (true)
        {
            message = "Client" + (counter++).ToString();
            lock (this)
            {
                sendBytes = Encoding.ASCII.GetBytes(message);
                udpSendState.counter = counter;
                // 调用发送回调函数
                udpSend.BeginSend(sendBytes, sendBytes.Length, new AsyncCallback(SendCallback), udpSendState);
                sendDone.WaitOne();
                Thread.Sleep(200);
                ReceiveMessages();
            }
        }
    }

    // 发送回调函数
    public void SendCallback(IAsyncResult iar)
    {
        UdpState udpState = iar.AsyncState as UdpState;
        if (iar.IsCompleted)
        {
            Console.WriteLine("第{0}个发送完毕!", udpState.counter);
            Console.WriteLine("number of bytes sent: {0}", udpState.udpClient.EndSend(iar));
            //if (udpState.counter == 10)
            //{
            //    udpState.udpClient.Close();
            //}
            sendDone.Set();
        }
    }

    // 接收函数
    public void ReceiveMessages()
    {
        lock (this)
        {
            udpReceive.BeginReceive(new AsyncCallback(ReceiveCallback), udpReceiveState);
            receiveDone.WaitOne();
            Thread.Sleep(100);
        }
    }

    // 接收回调函数
    public void ReceiveCallback(IAsyncResult iar)
    {
        UdpState udpState = iar.AsyncState as UdpState;
        if (iar.IsCompleted)
        {
            Byte[] receiveBytes = udpState.udpClient.EndReceive(iar, ref udpReceiveState.ipEndPoint);
            string receiveString = Encoding.Unicode.GetString(receiveBytes);
            Console.WriteLine("Received: {0}", receiveString);
            receiveDone.Set();
        }
    }

    // 主函数
    public static void Main()
    {
        ////获取本机可用IP地址  
        //IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
        //var ip = ips[ips.Length - 1];
        AsyncUdpClient auc = new AsyncUdpClient();
        //auc.localEP = new IPEndPoint(ip, listenPort);
        //auc.remoteEP = new IPEndPoint(ip, remotePort);
        auc.SendMsg();
        Console.Read();
    }
}

服务器端,需要先启动

// 定义 UdpState类
public class UdpState
{
    public UdpClient udpClient;
    public IPEndPoint ipEndPoint;
    public const int BufferSize = 1024;
    public byte[] buffer = new byte[BufferSize];
    public int counter = 0;
}
// 异步UDP类
public class AsyncUdpSever
{
    // 定义节点
    private IPEndPoint ipEndPoint = null;
    private IPEndPoint remoteEP = null;
    // 定义UDP发送和接收
    private UdpClient udpReceive = null;
    private UdpClient udpSend = null;
    // 定义端口
    private const int listenPort = 1100;
    private const int remotePort = 1101;
    UdpState udpReceiveState = null;
    UdpState udpSendState = null;
    // 异步状态同步
    private ManualResetEvent sendDone = new ManualResetEvent(false);
    private ManualResetEvent receiveDone = new ManualResetEvent(false);
    public AsyncUdpSever()
    {
        // 本机节点
        ipEndPoint = new IPEndPoint(IPAddress.Any, listenPort);
        // 远程节点
        IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
        var ip = ips[ips.Length - 1];
        remoteEP = new IPEndPoint(ip, remotePort);
        //remoteEP = new IPEndPoint(Dns.GetHostAddresses(Dns.GetHostName())[0], remotePort);
        // 实例化
        udpReceive = new UdpClient(ipEndPoint);
        udpSend = new UdpClient();

        // 分别实例化udpSendState、udpReceiveState
        udpReceiveState = new UdpState();
        udpReceiveState.udpClient = udpReceive;
        udpReceiveState.ipEndPoint = ipEndPoint;

        udpSendState = new UdpState();
        udpSendState.udpClient = udpSend;
        udpSendState.ipEndPoint = remoteEP;
    }
    public void ReceiveMsg()
    {
        Console.WriteLine("listening for messages");
        while (true)
        {
            lock (this)
            {
                // 调用接收回调函数
                IAsyncResult iar = udpReceive.BeginReceive(new AsyncCallback(ReceiveCallback), udpReceiveState);
                receiveDone.WaitOne();
                Thread.Sleep(100);
            }
        }
    }
    // 接收回调函数
    private void ReceiveCallback(IAsyncResult iar)
    {
        UdpState udpReceiveState = iar.AsyncState as UdpState;
        if (iar.IsCompleted)
        {
            Byte[] receiveBytes = udpReceiveState.udpClient.EndReceive(iar, ref udpReceiveState.ipEndPoint);
            string receiveString = Encoding.ASCII.GetString(receiveBytes);
            Console.WriteLine("Received: {0}", receiveString);
            //Thread.Sleep(100);
            receiveDone.Set();
            SendMsg();
        }
    }
    // 发送函数
    private void SendMsg()
    {
        udpSend.Connect(udpSendState.ipEndPoint);
        udpSendState.udpClient = udpSend;
        udpSendState.counter++;

        string message = string.Format("第{0}个UDP请求处理完成!", udpSendState.counter);
        Byte[] sendBytes = Encoding.Unicode.GetBytes(message);
        udpSend.BeginSend(sendBytes, sendBytes.Length, new AsyncCallback(SendCallback), udpSendState);
        sendDone.WaitOne();
    }
    // 发送回调函数
    private void SendCallback(IAsyncResult iar)
    {
        UdpState udpState = iar.AsyncState as UdpState;
        Console.WriteLine("第{0}个请求处理完毕!", udpState.counter);
        Console.WriteLine("number of bytes sent: {0}", udpState.udpClient.EndSend(iar));
        sendDone.Set();
    }

    // 主函数
    public static void Main()
    {
        ////获取本机可用IP地址  
        //IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
        //var ip = ips[ips.Length - 1];
        AsyncUdpSever aus = new AsyncUdpSever();
        //aus.ipEndPoint = new IPEndPoint(ip, listenPort);
        //aus.remoteEP = new IPEndPoint(ip, remotePort);
        Thread t = new Thread(new ThreadStart(aus.ReceiveMsg));
        t.Start();
        Console.Read();
    }

}

C#利用广播实现群发功能

服务端每 3 秒发送一次消息

先启动客户端,在启动服务端

服务端

class Program
{
    static void Main(string[] args)
    {
        UdpClient myUdpClient = new UdpClient();
        //让其自动提供子网中的IP广播地址  
        IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 8001);
        while (true)
        {
            try
            {
                //将发送内容转换为字节数组  
                byte[] bytes = Encoding.UTF8.GetBytes(DateTime.Now.ToString());
                //向子网发送信息  
                myUdpClient.Send(bytes, bytes.Length, iep);
                System.Threading.Thread.Sleep(3000);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                myUdpClient.Close();
            }

        }

    }
}

客户端

class Program
{
    //使用的接收端口号  
    private static int port = 8001;
    private static UdpClient udpClient;  

    static void Main(string[] args)
    {
        Thread myThread = new Thread(ReceiveData);
        //将线程设为后台运行  
        myThread.IsBackground = true;
        myThread.Start();

        Console.ReadKey();

    }

    /// 在后台运行的接收线程  
    /// </summary>  
    static void ReceiveData()
    {
        //在本机指定的端口接收  
        udpClient = new UdpClient(port);
        IPEndPoint remote = null;
        //接收从远程主机发送过来的信息;  
        while (true)
        {
            try
            {
                //关闭udpClient时此句会产生异常  
                byte[] bytes = udpClient.Receive(ref remote);
                string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
                Console.WriteLine(string.Format("来自{0}:{1}", remote, str));
            }
            catch
            {
                //退出循环,结束线程  
                break;
            }
        }
    }  

}

C#利用组播实现网络会议室功能(即群聊功能)

待续

C#利用UdpClient发送广播消息

首先写个接受消息的客户端。这里偷了点懒,new UdpClient(11000)就是用Udp方式侦听11000端口,侦听任何发送到11000端口的消息都会接收到。

代码 :

UdpClient udpClient = new UdpClient(11000); 
try 
{ 
    IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); 
    Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint); 
    string returnData = Encoding.ASCII.GetString(receiveBytes); 

    Console.WriteLine("This is the message you received " + 
                                 returnData.ToString()); 
    Console.WriteLine("This message was sent from " + 
                                RemoteIpEndPoint.Address.ToString() + 
                                " on their port number " + 
                                RemoteIpEndPoint.Port.ToString()); 

    udpClient.Close(); 
} 
catch (Exception e) 
{ 
    Console.WriteLine(e.ToString()); 
}

然后写个发Udp的服务器

代码 :

UdpClient udpClient = new UdpClient(11001); 
try 
{ 
    udpClient.Connect(IPAddress.Parse("192.168.0.255"), 11000);  
    Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody thereA?"); 

    udpClient.Send(sendBytes, sendBytes.Length); 

    udpClient.Close();

} 
catch (Exception e) 
{ 
    Console.WriteLine(e.ToString()); 
}

其中192.168.0.255是你的内网广播地址,11000是客户端的端口。

广播地址是通过你的子网掩码获得的例如你的网关是192.168.0.1,掩码是255.255.255.0,那么你的广播地址就是192.168.0.255.

C# UDP异步发送和接收

服务端

class Program
{
    protected static UdpClient P_UdpClient = new UdpClient(5123);

    static void Main(string[] args)
    {
        IPEndPoint P_IpEndPoint = new IPEndPoint(
            IPAddress.Any, 0);
        byte[] P_bt = P_UdpClient.Receive(ref P_IpEndPoint);
        P_UdpClient.BeginReceive(Get, P_UdpClient);

        Console.ReadKey();
    }

    static void Get(IAsyncResult ia)
    {
        UdpClient P_Udp = ia.AsyncState as UdpClient;
        IPEndPoint P_IpEndPoint = new IPEndPoint(
          IPAddress.Any, 0);
        byte[] P_bt = P_Udp.EndReceive(ia, ref P_IpEndPoint);
        Console.WriteLine(string.Format("信息:{0} IP地址:{1} 端口:{2}",
            Encoding.Default.GetString(P_bt),
            P_IpEndPoint.Address.ToString(),
            P_IpEndPoint.Port.ToString()));
        P_UdpClient.BeginReceive(Get, P_UdpClient);
    }
}

客户端

class Program
{
    static void Main(string[] args)
    {
        UdpClient P_UdpClient = new UdpClient();
        IPEndPoint P_IpEndPoint = new IPEndPoint(
            IPAddress.Parse("192.168.1.118"), 5123);
        int i = 0;
        while (true)
        {
            byte[] P_bt_Temp = Encoding.Default.GetBytes("你好!" + (i = ++i > 1000000 ? 0 : i).ToString());
            P_UdpClient.BeginSend(P_bt_Temp, P_bt_Temp.Length,
                P_IpEndPoint,
                (ia) =>
                {
                    UdpClient P_uc = ia.AsyncState as UdpClient;
                    Console.WriteLine("已经发送" + i.ToString());
                },
                    P_UdpClient);
            System.Threading.Thread.Sleep(10);
        }

        Console.ReadKey();
    }
}

#

站内公告

A PHP Error was encountered

Severity: Core Warning

Message: PHP Startup: zip: Unable to initialize module Module compiled with module API=20060613 PHP compiled with module API=20090626 These options need to match

Filename: Unknown

Line Number: 0

Backtrace: