【问题标题】:socket programming with ioctl TIOCOUTQ使用 ioctl TIOCOUTQ 进行套接字编程
【发布时间】:2018-03-21 15:17:48
【问题描述】:

只是一个简单的问题,我正在做一个原始套接字编程:

fd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);

并使用以下方式拉动发送缓冲区:

bytes = sendto(fd, &buffer, send_size, 0,(struct sockaddr*)&socket_addr, addr_size);

ioctl(fd, TIOCOUTQ, &bytes);
while(bytes>0)
    ioctl(fd, TIOCOUTQ, &bytes);

如果字节返回 0 并退出 while 循环,是否保证数据从设备发送出去?如果不是,我如何实际检查数据是否从设备发送出去?

【问题讨论】:

  • send() 函数将负责将数据发送出设备。 send(2) 的手册页声明 成功时,这些调用返回发送的字符数。出错时,返回 -1,并适当设置 errno。
  • 对不起,我正在使用 sendto
  • send() 就像sendto() 返回发送的字节数。但这并不一定意味着这些字节真的已经离开了线路,它可能存储在套接字缓冲区中并等待发送。 TIOCOUTQ 检索套接字缓冲区的大小,如果它是空的,它已经离开了 linux 网络子系统。这是尽可能接近的。它仍然可能在驱动程序或网卡本身中缓冲,因此您永远无法绝对确定它是否在线,但总的来说,它会按照您的预期进行。
  • @Ctx 我相信 send 的输出仅指正在排队的数据。它不能保证它确实被发送出去了。
  • @ShacharShemesh 嗯,这是我写的,对吗?

标签: c linux sockets raw-sockets


【解决方案1】:

这是我在 RS-485 收发器时用来驱动 TX 使能线以确保所有位都输出的:

void WaitTxDone(unsigned int messageSize)
{
    //wait for tty TX queue to become empty
    int queued = 1;
    while (queued > 0)
        ioctl(m_port->getPortHandle(), TIOCOUTQ, &queued);

    //number of nanoseconds it takes to transmit messageSize bytes (10 is 8 bits + start + stop)
    unsigned int txTime = ((float)(messageSize * 10) / m_baudrate) * 1000000000;

    //assuming it won't take longer than one second
    struct timespec delay = {0, txTime};
    nanosleep(&delay, NULL);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多