4

我为 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 中网络编程的最佳资源是什么?

4

2 回答 2

3

服务器上的 UDP 套接字未“连接”,因此您无法使用send. 它可能返回了一条您没有检查的错误消息。在服务器上,使用receiveFromwithsendTo回复消息。

Note that while UDP is a connectionless protocol, the socket API supports the concept of a connected UDP socket, which is merely the socket library remembering the target address for when you call send. It will also filter out messages not coming from the connected address when calling receive. Connected sockets are usually a bad fit for UDP server programs.

于 2012-10-05T01:43:04.617 回答
1

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

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

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

于 2012-10-04T17:27:19.780 回答