C# UDP套接字客户端和服务器

15

这是我的第一个问题。我很新于此类编程,之前只开发过.NET网站和表单。

现在,我所在的公司要求我制作一个ActiveX组件,监听UDP消息,并将其转换成事件。

UDP消息来自Avaya系统,所以我被告知要测试我的ActiveX,首先需要创建一个应用程序,仅发送UDP(只有一个按钮,发送预定义的UDP字符串)。然后创建一个普通的C#应用程序,用于从测试应用程序中获取那些传输的UDP字符串的监听套接字。这两个应用程序将在同一台机器上运行。

稍后,当我把这个做好了,就需要将监听器变成ActiveX组件,但首先要解决第一步。

我想知道是否有任何关于此的好教程,以及如何开始的任何想法?对不起,因为我真的很陌生,而且没有时间学习,因为这必须在2周内完成。

提前致谢。

编辑:我成功创建了两个简单的控制台应用程序,并在它们之间成功地发送了UDP消息。发送者仅用于测试,现在我需要重新制作我的接收器,以获取UDP消息并将其“翻译”为事件。最后,将其制作成ActiveX控件...

3个回答

48

简单的服务器和客户端:

public struct Received
{
    public IPEndPoint Sender;
    public string Message;
}

abstract class UdpBase
{
    protected UdpClient Client;

    protected UdpBase()
    {
        Client = new UdpClient();
    }

    public async Task<Received> Receive()
    {
        var result = await Client.ReceiveAsync();
        return new Received()
        {
            Message = Encoding.ASCII.GetString(result.Buffer, 0, result.Buffer.Length),
            Sender = result.RemoteEndPoint
        };
    }
}

//Server
class UdpListener : UdpBase
{
    private IPEndPoint _listenOn;

    public UdpListener() : this(new IPEndPoint(IPAddress.Any,32123))
    {
    }

    public UdpListener(IPEndPoint endpoint)
    {
        _listenOn = endpoint;
        Client = new UdpClient(_listenOn);
    }

    public void Reply(string message,IPEndPoint endpoint)
    {
        var datagram = Encoding.ASCII.GetBytes(message);
        Client.Send(datagram, datagram.Length,endpoint);
    }

}

//Client
class UdpUser : UdpBase
{
    private UdpUser(){}

    public static UdpUser ConnectTo(string hostname, int port)
    {
        var connection = new UdpUser();
        connection.Client.Connect(hostname, port);
        return connection;
    }

    public void Send(string message)
    {
        var datagram = Encoding.ASCII.GetBytes(message);
        Client.Send(datagram, datagram.Length);
    }

}

class Program 
{
    static void Main(string[] args)
    {
        //create a new server
        var server = new UdpListener();

        //start listening for messages and copy the messages back to the client
        Task.Factory.StartNew(async () => {
            while (true)
            {
                var received = await server.Receive();
                server.Reply("copy " + received.Message, received.Sender);
                if (received.Message == "quit")
                    break;
            }
        });

        //create a new client
        var client = UdpUser.ConnectTo("127.0.0.1", 32123);

        //wait for reply messages from server and send them to console 
        Task.Factory.StartNew(async () => {
            while (true)
            {
                try
                {
                    var received = await client.Receive();
                    Console.WriteLine(received.Message);
                    if (received.Message.Contains("quit"))
                        break;
                }
                catch (Exception ex)
                {
                    Debug.Write(ex);
                }
            }
        });

        //type ahead :-)
        string read;
        do
        {
            read = Console.ReadLine();
            client.Send(read);
        } while (read != "quit");
    }
}

由于OP明确要求使用UDP,您不应该引导他走错方向。UdpClient(http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient(v=vs.110).aspx)将是解决他问题的更好选择... - Roland Bär
批准了!通过一个小演示纠正了我的错误。 - lboshuizen
谢谢。这确实帮助我更好地理解了它的工作原理,并成功创建了两个简单的控制台应用程序(监听器和发送器),并在它们之间成功发送UDP消息。发送器仅用于测试,现在我需要重新制作我的接收器以获取UDP消息并将其“转换”为事件。最后,将其制作为ActiveX控件...有任何提示从哪里开始吗?请注意,我以前已经做过这个,但是输入是事件,现在将获得字符串,并且为桌面应用程序完成了此操作,现在我需要将该代码拿出来并创建一个ActiveX.. 愚蠢的业务 :) - Paul
你的电子邮件地址未在个人资料中显示。可以请你提供一下吗?谢谢。顺便说一句,我重新创建了WinForms应用程序,在一个电脑上作为发送方,在我的笔记本电脑上作为接收方。当发送方发送UDP字符串时,接收方接收到并触发一个事件,提示“你收到了UDP消息:我的字符串内容”。接下来是ActiveX。 - Paul
好的,成功制作了一个ActiveX控件。它调用一个名为“startthread”的函数,并等待事件。该事件是来自Avaya服务器的UDP消息。正在侦听的函数解释该字符串,并将数据与一些附加信息写入数据库以及log.txt中。我的最后一个任务是-将数据返回给调用StartThread函数的Web应用程序(该函数应在后台运行)。有什么方法可以做到这一点吗? - Paul
显示剩余2条评论

10

简单的服务器和客户端:

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

class Program
{
    static void Main(string[] args)
    {
        // Create UDP client
        int receiverPort = 20000;
        UdpClient receiver = new UdpClient(receiverPort);

        // Display some information
        Console.WriteLine("Starting Upd receiving on port: " + receiverPort);
        Console.WriteLine("Press any key to quit.");
        Console.WriteLine("-------------------------------\n");

        // Start async receiving
        receiver.BeginReceive(DataReceived, receiver);

        // Send some test messages
        using (UdpClient sender1 = new UdpClient(19999))
            sender1.Send(Encoding.ASCII.GetBytes("Hi!"), 3, "localhost", receiverPort);
        using (UdpClient sender2 = new UdpClient(20001))
            sender2.Send(Encoding.ASCII.GetBytes("Hi!"), 3, "localhost", receiverPort);

        // Wait for any key to terminate application
        Console.ReadKey();
    }

    private static void DataReceived(IAsyncResult ar)
    {
        UdpClient c = (UdpClient)ar.AsyncState;
        IPEndPoint receivedIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
        Byte[] receivedBytes = c.EndReceive(ar, ref receivedIpEndPoint);

        // Convert data to ASCII and print in console
        string receivedText = ASCIIEncoding.ASCII.GetString(receivedBytes);
        Console.Write(receivedIpEndPoint + ": " + receivedText + Environment.NewLine);

        // Restart listening for udp data packages
        c.BeginReceive(DataReceived, ar.AsyncState);
    }
}

2

服务器

public void serverThread()
{
    UdpClient udpClient = new UdpClient(8080);
    while(true)
    {
        IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
        Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
        string returnData = Encoding.ASCII.GetString(receiveBytes);
        lbConnections.Items.Add(RemoteIpEndPoint.Address.ToString() 
                                + ":" +  returnData.ToString());
    }
}

并初始化线程

private void Form1_Load(object sender, System.EventArgs e)
{
    Thread thdUDPServer = new Thread(new ThreadStart(serverThread));
    thdUDPServer.Start();
}

客户端

private void button1_Click(object sender, System.EventArgs e)
{
    UdpClient udpClient = new UdpClient();
    udpClient.Connect(txtbHost.Text, 8080);
    Byte[] senddata = Encoding.ASCII.GetBytes("Hello World");
    udpClient.Send(senddata, senddata.Length);
}

将其插入到按钮命令中。

来源:http://technotif.com/creating-simple-udp-server-client-transfer-data-using-c-vb-net/


以下是您需要的命名空间: "using System.Threading;" "using System.Net;" "using System.Net.Sockets;" "using System.Text;" - rmustakos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接