简单的UDP示例,用于从同一个套接字发送和接收数据

时间:2013-11-18 02:13:33

标签: c# udp

出于某种原因,我很难从同一个套接字发送和接收数据。无论如何,这是我的客户代码:

var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening (testing localy)
client.Connect(ep); 

// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);

// then receive data
var receivedData = client.Receive(ref ep);  // Exception: An existing connection was forcibly closed by the remote host

基本上我想创建一个协议,我发送一个udp数据包,然后我期待一个响应。就像每个请求的HTTP协议一样,都有响应。如果服务器位于不同的计算机上,则此代码有效。可能存在服务器和客户端在同一台计算机上的情况。

这是服务器:

UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);

while (true)
{
    var groupEP = new IPEndPoint(IPAddress.Any, 11000); // listen on any port
    var data = udpServer.Receive(ref groupEP);
    udpServer.Send(new byte[] { 1 }, 1); // if data is received reply letting the client know that we got his data          
}

修改

我不能使用tcp的原因是因为有时客户端在NAT(路由器)后面,并且比TCP更容易进行UDP打孔。


解决方案:

感谢markmnl回答这里是我的代码:

服务器:

UdpClient udpServer = new UdpClient(11000);

while (true)
{
    var remoteEP = new IPEndPoint(IPAddress.Any, 11000); 
    var data = udpServer.Receive(ref remoteEP); // listen on port 11000
    Console.Write("receive data from " + remoteEP.ToString());
    udpServer.Send(new byte[] { 1 }, 1, remoteEP); // reply back
}

客户代码:

var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening
client.Connect(ep);

// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);

// then receive data
var receivedData = client.Receive(ref ep);

Console.Write("receive data from " + ep.ToString());

Console.Read();

3 个答案:

答案 0 :(得分:25)

(我认为您知道使用UDP(用户数据报协议)不保证传送,检查重复和拥塞控制,并且只会回答您的问题。)

在您的服务器中这一行:

var data = udpServer.Receive(ref groupEP);

重新分配groupEP你所拥有的地址。

这一行:

udpServer.Send(new byte[] { 1 }, 1); 

由于您未指定将数据发送到的人,因此无效。 (它适用于您的客户端,因为您调用了连接,这意味着发送将始终发送到您连接的端点,当然我们不希望在服务器上,因为我们可以拥有许多客户端)。我会:

UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);

while (true)
{
    var remoteEP = new IPEndPoint(IPAddress.Any, 11000);
    var data = udpServer.Receive(ref remoteEP);
    udpServer.Send(new byte[] { 1 }, 1, remoteEP); // if data is received reply letting the client know that we got his data          
}

此外,如果您在同一台计算机上安装了服务器和客户端,则应将它们放在不同的端口上。

答案 1 :(得分:1)

我会尽量保持简短,几个月前我已经完成了this一款我试图制作的游戏,它做了一个像TCP一样的UDP“客户端-服务器”连接,可以使用此发送(消息)(消息+对象)。我已经对其进行了一些测试,并且效果很好,请根据需要随时对其进行修改。

答案 2 :(得分:0)

这是我的解决方案,用于定义远程和本地端口,然后将接收到的数据写到文件中,并将其全部放入您选择的具有正确导入的类中

    static UdpClient sendClient = new UdpClient();
    static int localPort = 49999;
    static int remotePort = 49000;
    static IPEndPoint localEP = new IPEndPoint(IPAddress.Any, localPort);
    static IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), remotePort);
    static string logPath = System.AppDomain.CurrentDomain.BaseDirectory + "/recvd.txt";
    static System.IO.StreamWriter fw = new System.IO.StreamWriter(logPath, true);


    private static void initStuff()
    {
      
        fw.AutoFlush = true;
        sendClient.ExclusiveAddressUse = false;
        sendClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        sendClient.Client.Bind(localEP);
        sendClient.BeginReceive(DataReceived, sendClient);
    }

    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);
        fw.WriteLine(DateTime.Now.ToString("HH:mm:ss.ff tt") +  " (" + receivedBytes.Length + " bytes)");

        c.BeginReceive(DataReceived, ar.AsyncState);
    }


    static void Main(string[] args)
    {
        initStuff();
        byte[] emptyByte = {};
        sendClient.Send(emptyByte, emptyByte.Length, remoteEP);
    }