2012-10-04 54 views
4

我已經爲UDP迴應客戶端和服務器創建了一個玩具示例。但是,我沒有收到服務器的回覆,我不知道我做錯了什麼。D語言:UDP客戶端沒有收到回覆

客戶:

#!/usr/bin.rdmd 
import std.stdio; 
import std.socket; 
import std.string; 
import std.conv; 
import std.random; 
import std.outbuffer; 

int main(string[] args) { 
    if (args.length != 3) { 
    writefln("usage: %s <server host> <port>",args[0]); 
    return 0; 
    } 

    auto s = new UdpSocket(); 

    auto addr = new InternetAddress(args[1], to!ushort(args[2])); 
    s.connect(addr); 
    scope(exit) s.close(); 

    for (int i = 0; i < 1000; i++){ 
    auto r = uniform(int.min,int.max); 
    auto send_buf = new OutBuffer(); 

    send_buf.write(r); 

    s.send(send_buf.toBytes()); 

    ubyte[r.sizeof] recv_buf; 
    s.receive(recv_buf); 

    assert(r == *cast(int*)(send_buf.toBytes().ptr)); 
    } 



    return 0; 
} 

服務器:

#!/usr/bin.rdmd 
import std.stdio; 
import std.socket; 
import std.string; 
import std.conv; 

int main(string[] args) { 
    if (args.length != 2) { 
    writefln("usage: %s <port>",args[0]); 
    return 0; 
    } 

    auto s = new UdpSocket(); 

    auto addr = new InternetAddress("localhost", to!ushort(args[1])); 
    s.bind(addr); 

    while (true){ 
    ubyte[int.sizeof] recv_buf; 
    s.receive(recv_buf); 

    writefln("Received: %s\n",recv_buf); 

    s.send(recv_buf); 


    } 

    writeln("sent"); 

    return 0; 
} 

如果你執行你會看到,客戶端掛在接收,而服務器已經發送回復的程序。

你知道我在做什麼錯嗎?

順便說一句,D中網絡編程的最佳資源是什麼?

回答

2

服務器上的UDP套接字未「連接」,因此您不能使用send。它可能會返回一條您沒有檢查的錯誤消息。在服務器上,使用receiveFromsendTo來回復郵件。

請注意,儘管UDP是無連接協議,但套接字API支持所連接的UDP套接字的概念,該套接字只是在您撥打send時記住目標地址的套接字庫。當撥打receive時,它也會過濾掉不是來自連接地址的信息。連接的套接字通常不適合UDP服務器程序。

1

receive()receiveFrom()會默認阻止。這很可能是爲什麼它掛起。在緩衝區大小不夠的情況下,send()也可能會阻塞。在處理UDP時應該使用sendTo()和receiveFrom()方法。另外,如果你想從「服務器」向你的「客戶端」發送一些數據,那麼基本上兩者都應該被編碼爲服務器和客戶端,並且都應該知道他們發送數據包的地址,所以你會考慮到這一點,必須重構代碼。

很久以前我開始網絡編程Beej's Guide是最好的,我仍然認爲它是。您應該能夠輕鬆將該指南中的C源端口移至D.