面试题答案
一键面试-
记录时间和字节数:
- 定义变量记录上一次发送数据的时间戳(例如使用
struct timeval
获取精确时间),以及已发送的字节总数。 struct timeval last_send_time;
ssize_t total_sent_bytes = 0;
- 定义变量记录上一次发送数据的时间戳(例如使用
-
计算时间间隔:
- 在每次调用发送函数前,获取当前时间,计算距离上一次发送数据的时间间隔。
struct timeval current_time;
gettimeofday(¤t_time, NULL);
long elapsed_time = (current_time.tv_sec - last_send_time.tv_sec) * 1000000 + (current_time.tv_usec - last_send_time.tv_usec);
-
根据带宽限制判断:
- 假设设定的带宽为
max_bytes_per_second
,根据时间间隔计算在这段时间内允许发送的最大字节数allowed_bytes
。 double allowed_bytes = (double)max_bytes_per_second * elapsed_time / 1000000;
- 如果已发送的字节数加上本次要发送的字节数
bytes_to_send
超过了allowed_bytes
,则等待。 - 等待的方式可以是使用
select
或usleep
函数。例如,计算需要等待的时间(微秒): long wait_usec = (total_sent_bytes + bytes_to_send - allowed_bytes) * 1000000 / max_bytes_per_second;
usleep(wait_usec);
- 假设设定的带宽为
-
更新时间和字节数:
- 发送数据后,更新上次发送时间为当前时间,更新已发送字节总数。
last_send_time = current_time;
total_sent_bytes += bytes_sent;
(bytes_sent
为实际发送的字节数)
-
发送函数选择:
- 使用
send
或sendto
函数进行网络数据发送,根据具体是TCP还是UDP选择合适的函数。例如,对于TCP: ssize_t bytes_sent = send(sockfd, buffer, len, 0);
- 对于UDP:
ssize_t bytes_sent = sendto(sockfd, buffer, len, 0, (struct sockaddr *)&dest_addr, addrlen);
- 使用