我有一个应用程序,其主要目的是将RTP流转换为HTTP流。一个线程正在接收RTP数据包并将它们写入循环缓冲区,另一个线程充当迷你网络服务器,并通过从该缓冲区读取来应答HTTP请求(一次只能发生一个GET请求)。在send()中很长的块,似乎与线程有关,而不是TCP
一旦接收到GET,这个HTTP线程就是一个简单的循环,只要循环缓冲区中有东西,就调用send()。但是有时候,send()会阻塞大量的时间(比如> 1s),从而产生音频丢失。
要清楚的是,RTP数据包能够实时到达,而不会在这里超过或下溢。 HTTP套接字是故意阻塞的,因为预期当接收器不需要音频(在其自己的缓冲器上足够多)时,接收器使用TCP来调节其流。但是HTTP客户端并没有被音频所淹没,因为RTP源再次只是在实时执行。
但是,很明显,发生了其他事情,我观察到在Linux,MacOS和Windows(代码适用于所有这些)以及两种不同的网络拓扑结构上。
我想知道如果在send()长的块不是起因于TCP流量控制别的东西,像什么我有什么情况发生时,在发送线程块()
谢谢 - 我不介意线程被阻塞,因为在这一点上它的唯一目的是发送数据,但你指出可能真正的问题是数据包丢失和ACK超时。如果可以在每个套接字的基础上改变,我必须进行投资。我可能没有看到与其他音频应用程序的问题,因为他们有可能提前发送大量音频,所以网络连接是 –
评论超时:-( 我必须调查是否以及如何TCP窗口和相关参数可以在每个插槽的基础上改变,我从来没有看到 我试过的两个网络肯定不是非常可靠,因为我可以看到,在RTP(UDP)端有很多丢失的paquet,我必须要求重新发送 –
您需要增加SO_SNDBUF,因为这样可以减少一些此类问题,因为它可以为您提供一个更大的“泄漏桶”来处理。另一个需要研究的问题是如何降低每个套接字或系统上的TCP RTO值(这个**不是** SO_SNDTIMEO - 这是不同的)由于RTO是一个动态值,可以在连接保持打开状态时进行调节,所以您可能需要调整系统设置。尝试[man 7 tcp](https://linux.die。net/man/7/tcp),或者搜索“tcp socket change rto”。关于这个话题有很多需要阅读。 – selbie