我正在编写一个通过setsockopt()
使用TCP Fast Open选项的小型服务器。但是我从gcc收到此错误:
$gcc server.c
server.c: In function 'main':
server.c:35:34: error: 'TCP_FASTOPEN' undeclared (first use in this function)
if (setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen) == -1)
这是服务器的代码:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
int main(int argc, char *argv[])
{
short port = 45000;
int max_conn = 10;
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
{
printf("Couldn't create socket: %s\n", strerror(errno));
return -1;
}
struct sockaddr_in ssi;
ssi.sin_family = AF_INET;
ssi.sin_port = htons(port);
ssi.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *)&ssi, sizeof(struct sockaddr_in)) != 0)
{
printf("Couldn't bind socket: %s\n", strerror(errno));
return -1;
}
// TFO
int qlen = 5;
if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) == -1)
{
printf("Couldn't set TCP_FASTOPEN option: %s\n", strerror(errno));
return -1;
}
if (listen(fd, max_conn) != 0)
{
printf("Could'nt listen on socket: %s\n", strerror(errno));
return -1;
}
struct sockaddr_in csi;
int clen = sizeof(csi);
int cfd = accept(fd, (struct sockaddr *)&csi, &clen);
return 0;
}
为什么gcc会出现此错误?
宏TCP_FASTOPEN
位于内核中的include/uapi/linux/tcp.h
,其值为23,所以我尝试在我的代码中重新定义它,然后它编译并运行但是该选项不是由服务器作为TFO请求的答案(在SYN-ACK中)。
有人知道为什么吗?这与编译问题有关吗?
答案 0 :(得分:3)
/proc/sys/net/ipv4/tcp_fastopen
needs to be set to 2启用服务器端使用TCP快速打开选项:
tcp_fastopen文件可用于查看或设置一个值,该值可用于操作TFO功能的不同部分。在该值中设置位0(即值1)启用客户端TFO功能,以便应用程序可以请求TFO cookie。设置位1(即值2)启用服务器TFO功能,以便服务器TCP可以响应客户端的请求生成TFO cookie。 (因此,值3将在主机上启用客户端和服务器TFO功能。)
此外,TCP_FASTOPEN宏需要包含在#include <netinet/tcp.h>
中。
答案 1 :(得分:0)
看起来你的glibc不支持TCP_FASTOPEN - 即使你的内核有(因为当你包含标准套接字头时它不可用)。所以你不能真正使用glibc glue代码(其中setsockopt()
是其中一部分)。