0

所以,我有以下代码在 TCP 上发送我的数据包。它工作得很好。我只需要测试部分写入。因此,我通过将 sendbuf 设置为 1 或进行 hack,一次写入 1 个字节,如下所示。当我使用 tcpdump 时,除了第一个字节外,它都是不正确的。我做错了什么?

int tmi_transmit_packet(struct tmi_msg_pdu *tmi_pkt, int len, int *written_len)
{
int bytes;

// This works
bytes = write(g_tmi_mgr->tmi_conn_fd, (void*) tmi_pkt, len); 

// This doesn't: 
// bytes = write(g_tmi_mgr->tmi_conn_fd, (void*) tmi_pkt, 1); 

if (bytes < 0) {
    if (errno == EAGAIN) {
        return (TMI_SOCK_FULL);
    }
    return (TMI_WRITE_FAILED);
} else if (bytes < len) {
    *written_len += bytes;
    tmi_pkt += bytes;
    return (tmi_transmit_packet(tmi_pkt, len - bytes, written_len));
} else {
    *written_len += len;
}
return TMI_SUCCESS;
}
4

1 回答 1

2

这条线

tmi_pkt += bytes;

最有可能不会做你所期望的。

它确实增加tmi_pktsizeof(*tmp_pkt) * bytes,而不仅仅是增加了bytes。有关指针算术的一个很好的解释,您可能想单击此处并查看 binky

为了解决这个问题,你可以修改你的代码如下:

...
else if (bytes < len) {
  void * pv = ((char *) tmp_pkt) + bytes;
  *written_len += bytes;
  return (tmi_transmit_packet(pv, len - bytes, written_len));
}
...

无论如何,这在某种程度上闻起来很脏,因为传递给写入函数的指针指向的数据不一定需要对应于它的类型。

所以一个更干净的解决方案是不使用而是struct tmi_msg_pdu *tmi_pkt作为函数参数声明。void *char *

尽管这里没有必要也不推荐使用递归调用。对于大量数据和/或慢速传输,它可能会耗尽堆栈内存。一个简单的循环也可以。后者的优点是您可以使用指向要写入的缓冲区的临时指针,并且可以坚持类型化接口。

于 2013-03-15T07:23:35.863 回答