D语言:UDP客户端没有收到回复

时间:2012-10-04 14:56:36

标签: sockets udp d udpclient

我为UDP echo客户端和服务器创建了一个玩具示例。但是,我没有收到服务器的回复,我想知道我做错了什么。

客户端:

#!/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;
}

如果您执行程序,您将看到客户端在接收时挂起,而服务器已经发送了回复。

你知道我做错了什么吗?

BTW,D中网络编程的最佳资源是什么?

2 个答案:

答案 0 :(得分:3)

服务器上的UDP套接字未“连接”,因此您无法使用send。它可能返回了您未检查的错误消息。在服务器上,使用receiveFromsendTo来回复邮件。

请注意,虽然UDP是一种无连接协议,但套接字API支持连接的UDP套接字的概念,它只是一个套接库,可以在调用send时记住目标地址。它还会在调用receive时过滤掉非来自连接地址的消息。连接的套接字通常不适合UDP服务器程序。

答案 1 :(得分:1)

默认情况下,

receive()receiveFrom()会被屏蔽。这很可能就是它挂起的原因。 send()也可能阻塞缓冲区大小不够的情况。处理UDP时应该使用sendTo()和receiveFrom()方法。

此外,如果你想将一些数据从“服务器”发送到你的“客户端”,那么基本上两者都应该被编码为服务器和客户端,并且两者都应该知道他们发送数据包的地址,所以你将拥有为此重构您的代码。

很久以前,当我开始网络编程Beej's Guide是最好的,我仍然认为它是。您应该能够轻松地将该指南中的C源插入D。