4

对于学校的一个编程项目,我们必须使用 tcp 协议和 udp 协议设计一个基本的客户端/服务器设置。我已经使用 C Socket 库中的 read() 和 write() 让 TCP 工作了。我现在需要创建一个“可靠的 UDP”系统。例如:

“当服务器接收到长度消息时,它将等待最多 500 毫秒以发送该字节数。如果它接收到正确的字节数,它将以包含字符“ACK”的字符串进行响应(常见缩写为确认)。如果在超时期限结束时没有收到正确的字节数,服务器将放弃并静默退出。

我设置了 sendto() 和 recvfrom() 函数,但我不确定如何执行超时功能,以便它只等待 500ms 发送第二个 msg。如果它没有收到“ACK”并重新发送长度 msg + msg 几次,我也必须稍后在客户端执行此操作。我该如何做超时?

4

2 回答 2

5

在您的程序中添加以下函数并使用它,而不是直接使用 recvfrom 函数。

以下functiong与recvfrom函数的输入参数相同+最后一个超时输入参数

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

int timeout_recvfrom (int sock, char *buf, int *length, struct sockaddr_in *connection, int timeoutinseconds)
{
    fd_set socks;
    struct timeval t;
    FD_ZERO(&socks);
    FD_SET(sock, &socks);
    t.tv_sec = timeoutinseconds;
    if (select(sock + 1, &socks, NULL, NULL, &t) &&
        recvfrom(sock, buf, *length, 0, (struct sockaddr *)connection, length)!=-1)
        {
        return 1;
        }
    else
        return 0;
}
于 2012-10-03T17:29:12.990 回答
4

不使用 select 或 poll 的替代方法是使用套接字选项 SO_RCVTIMEO 和 SO_SNDTIMEO

tv.tv_sec = 10; /* seconds */
tv.tv_usec = 0;

if(setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
        printf("Cannot Set SO_SNDTIMEO for socket\n");

if(setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
        printf("Cannot Set SO_RCVTIMEO for socket\n");

SO_RCVTIMEO 和 SO_SNDTIMEO 套接字选项

如果您有一个单独的套接字可以读取或写入/写入,那么这是一个更好的选择。如果您正在使用多个套接字并希望继续使用一个完全发送/接收数据的套接字,那么也许 select 会更合适。

于 2012-10-04T05:49:01.190 回答