当前位置: 首页 > 知识库问答 >
问题:

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

邹宏峻
2023-03-14

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

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(路由器)后面,并且做UDP打孔比TCP更简单。

感谢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个答案

孟开宇
2023-03-14

这是我定义远程和本地端口,然后将接收到的数据写出到文件中的解决方案,将它们全部放入您选择的一类中,并进行正确的导入

    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);
    }
鲁阳焱
2023-03-14

我会尽量保持简短,几个月前我已经为一个我正在尝试构建的游戏这样做了,它做了一个UDP“客户端-服务器”连接,就像TCP一样,你可以使用它发送(消息)(消息对象)。我已经用它做了一些测试,它工作得很好,如果需要的话可以随意修改

敖子安
2023-03-14

(我想你知道使用UDP(用户数据报协议)并不能保证交付,检查重复和拥塞控制,只会回答你的问题)。

在您的服务器中,这一行:

var data = udpServer.Receive(ref groupEP);

group pEP从您拥有的内容重新分配给您收到内容的地址。

这一行:

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

将不起作用,因为您尚未指定将数据发送给谁。(它适用于您的客户端,因为您调用了连接,这意味着发送将始终发送到您连接到的endpoint,当然我们不希望在服务器上这样做,因为我们可能有很多客户端)。我会:

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          
}

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

 类似资料:
  • 我想使用Qt UDP(不是TCP)套接字传输文件。所以我这样写代码: 看来要传输的Qt UDP数据包的最小大小是8192字节。接收方总是得到第一个数据包,但不能接收其他数据包。 我对Qt和网络编程的经验很少,所以我不知道我的猜想对不对。你能告诉我如何改变这些代码来支持在第一个数据包之后接收数据包,这样我就可以传输大数据了吗?

  • 问题内容: 我正在使用套接字连接我的Android应用程序(客户端)和Java后端服务器。每次与服务器通信时,我都希望从客户端发送两个数据变量。 1)某种消息(由用户通过界面定义) 2)消息的语言(由用户通过界面定义) 我该如何发送这些消息,以便服务器将每个消息解释为一个单独的实体? 在读取了服务器端的数据并做出了适当的结论之后,我想向客户端返回一条消息。(我想我会没事的) 因此,我的两个问题是如

  • 因此,我正在用Java编写一个程序,在DatagramSocket和DataGramPacket的帮助下发送和接收数据。问题是,当我发送数据/接收数据时,数据在我发送的程序中也会有所不同,但只是在某些情况下,比如: 但有时会起作用,比如:

  • 如何将数据从PHP页面发送到TCP端口? 我正在使用它,但我不能使用任何数据!还有,你知道我怎么才能暂停吗? 有什么问题?

  • 我一直在开发一个简单的python套接字聊天室,客户端和服务器可以在其中相互发送消息。我遇到的问题是服务器和客户端一次只能发送一条消息。我希望它能像任何其他聊天室一样工作,在那里我可以在发送消息时收到消息,任何帮助都会有很大帮助