tcp数据发送过快的处理
I also faced the same problem few weeks ago when implementing a VoIP server. After spending several days I could come up with a solution. As many others mentioned, there is no any direct system call to do the job. Instead,
- You can check if we have received the
ACK
after sending a packet withTCP_INFO
option. - If we haven't received the
ACK
, wait for few milliseconds and check again.
This may continue until a time out reaches. You have to implement it as a wrapper function to send() call. You will need tcp_info
struct from <netinet/tcp.h>
. It is the data structure for holding information about your tcp connection.
Here is the pseudo code
int blockingSend(const char *msg, int msglen, int timeout) {
std::lock_guard<std::mutex> lock(write_mutx);
int sent = send(sock_fd, msg, msglen, 0);
tcp_info info;
auto expireAt = chrono::system_clock::now() + chrono::milliseconds(timeout);
do {
this_thread::sleep_for(milliseconds(50));
getsockopt(sock_fd,SOL_TCP, TCP_INFO, (void *) &info, sizeof(info));
//wait till all packets acknowledged or time expires
} while (info.tcpi_unacked > 0 && expireAt > system_clock::now());
if(info.tcpi_unacked>0) {
cerr << "no of unacked packets :" << info.tcpi_unacked << endl;
return -1;
}
return sent;
}
Here tcpi_unacked
member holds the number of packets unacknowledged of your connection. If you read it soon after the send() call, it will contain number of unacked packets which is equal to number of packets sent. With time, number of unacked packets will be decremented to zero. Therefore you need to periodically check the value of tcpi_unacked
till it reaches zero. If the connection is half opened, you will never receive ACK
s while causing a endless loop. For such scenarios you may need to add a timeout mechanism as implemented above.
Even though this question has been asked long ago, this answer may help some one who has faced the same problem. I must mention that there could be more accurate solutions to this problem than this solution. Since I am a newbie to system programming and C/C++ this is what I could come up with.
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步