【问题标题】:How to Properly Set up a UDP Socket using UDP_CORK如何使用 UDP_CORK 正确设置 UDP 套接字
【发布时间】:2012-05-24 20:47:37
【问题描述】:

我已经在 UDP 下创建了一个回显服务器,并且正在开发一个客户端,它将给定文件拆分为数据包并将其传输到服务器,然后服务器返回数据包以由客户端重新组合。

发送单个数据包就可以了。但是,我正在尝试使用 UDP_CORK 套接字选项在一个数据包中传输尽可能多的文件部分。我正在使用以下代码:

#define LINE_SIZE 80

...
// s = socket descriptor.
...

int one = 1;
int zero = 0;

setsockopt(s, IPPROTO_UDP, UDP_CORK, &one, sizeof(one));  // cork

/* Send to server, receive from server, write to new file. */

FILE *orig, *copy;
char line[LINE_SIZE];

if ((orig = fopen(input + 3, "rb")) == NULL) // original file
    print_error(input);

if ((copy = fopen(filename, "wb")) == NULL)  // copy of file
    print_error("fopen");

while (fread(line, sizeof(char), LINE_SIZE, orig) > 0) {
    if (sendto(s, line, LINE_SIZE, 0, (struct sockaddr *)&srv, len) == -1)
    print_error("sendto");
}

setsockopt(s, IPPROTO_UDP, UDP_CORK, &zero, sizeof(zero));  // uncork

if (recvfrom(s, line, LINE_SIZE, 0, (struct sockaddr *)&srv, &len) == -1)
    print_error("recvfrom");

fwrite(line, sizeof(char), LINE_SIZE, copy);

服务器表明它只接收一个“正常大小”的数据包,而不是我想要的软木数据包。因此,它只发回这个正常的数据包,由客户端通过 recvfrom() 调用接收。

我不确定我是否正确设置了 UDP_CORK。第二个论点正确吗?我不熟悉第二个选项的真正含义,因为手册页并不完全清楚。我也可能误解了软木塞的工作原理。

需要注意的几点:

  • 我认为自己是一名中级程序员,但我几乎没有网络编程经验。
  • 我意识到 UDP 不是传输文件的最佳方式。这最终将适应我正在帮助开发的不同协议。

谢谢!

【问题讨论】:

    标签: c sockets network-programming udp setsockopt


    【解决方案1】:

    文件有多大?您知道 UDP 数据报的大小限制为 64K,对吧?然后任何超过 1472 字节(1500 字节的可用以太网有效负载减去最少 20 字节的 IP 标头,最少 8 字节的 UDP 标头)都被 IP 分段。

    那么你永远不会检查setsockopt(2) 的返回值。你怎么知道它成功了?

    然后fread(3) 告诉您它读取了多少,但您仍然尝试发送LINE_SIZE 字节。这是错误的。

    【讨论】:

    • 说的很对。我没有考虑大小,并且我尝试的文件在 1472 阈值之后很久之前没有很多描述性字节。感谢您指出我的其他失误。但是,当数据报被 IP 分片时,其余的不应该在一个或多个数据包中发送吗?我只收到第一个。
    • 内核可能拒绝将大于 MTU 大小的数据打包到一个数据报中,尽管我不确定,但您收到的第一个块指向该方向的事实。使用碎片,你不会得到数据报的一部分——你要么得到全部,要么什么都没有。
    猜你喜欢
    • 2010-10-15
    • 2012-11-12
    • 2011-03-04
    • 1970-01-01
    • 2021-06-13
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多