簡體   English   中英

從同一套接字發送和接收數據的簡單 UDP 示例

[英]Simple UDP example to send and receive data from same socket

出於某種原因,我很難從同一個套接字發送和接收數據。 無論如何,這是我的客戶端代碼:

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();

(我假設您知道使用 UDP(用戶數據報協議)並不能保證交付、檢查重復項和擁塞控制,並且只會回答您的問題)。

在您的服務器中,這一行:

var data = udpServer.Receive(ref groupEP);

groupEP從您擁有的地址重新分配到您收到的地址。

這一行:

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

將不起作用,因為您尚未指定將數據發送給誰。 (它適用於您的客戶端,因為您調用了 connect 這意味着 send 將始終發送到您連接的端點,當然我們不希望在服務器上這樣做,因為我們可能有很多客戶端)。 我會:

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          
}

此外,如果您在同一台機器上有服務器和客戶端,您應該將它們放在不同的端口上。

我會盡量保持簡短,幾個月前我已經為我試圖構建的游戲完成了這個,它執行了一個像 TCP 一樣的 UDP“客戶端-服務器”連接,你可以發送(消息)(消息+ 對象)使用這個。 我已經用它做了一些測試,它工作得很好,如果需要,請隨時修改它。

這是我定義遠程和本地端口的解決方案,然后將接收到的數據寫入文件,將所有這些都放入您選擇的具有正確導入的類中

    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);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM