#linux #tcp #tcp-keepalive
#linux #tcp #tcp-keepalive
Вопрос:
Я попытался реализовать TCP-клиент для отправки запроса TCP keep alive, но все опции были сброшены с недопустимым аргументом. Мой код выглядит так, как показано ниже:
#define SERVER_ADDRESS "94.23.3.169" /* Server address */
#define PORT 1010/* the port client will be connecting to */
static int16_t i16Sockfd;
void vEnablekeepalive(int16_t i16Sockfd;)
{
int16_t i16Enable;
socklen_t optlen = sizeof(i16Enable);
/* Check the status for the keepalive option */
if(getsockopt(i16Sockfd, SOL_SOCKET, SO_KEEPALIVE, amp;i16Enable, amp;optlen) < 0) {
perror("getsockopt");
}
MSG("Before KEEP_ALIVE OPTION:%dn",i16Enable);
i16Enable = 1;
if(setsockopt(i16Sockfd, SOL_SOCKET, SO_KEEPALIVE, amp;i16Enable, sizeof(i16Enable)) == -1){
perror("setsockopt");
}
/* Check the status for the keepalive option */
if(getsockopt(i16Sockfd, SOL_SOCKET, SO_KEEPALIVE, amp;i16Enable, amp;optlen) < 0) {
perror("getsockopt);
}
MSG("After KEEP_ALIVE OPTION:%dn",i16Enable);
int16_t i16Idle = 600;
if(setsockopt(i16Sockfd, IPPROTO_TCP, TCP_KEEPIDLE, amp;i16Idle, sizeof(i16Idle)) == -1){
perror("Idle");
}
int16_t i16Interval = 60;
if(setsockopt(i16Sockfd, IPPROTO_TCP, TCP_KEEPINTVL, amp;i16Interval, sizeof(i16Interval)) == -1){
perror("Interval");
}
int16_t i16Maxcount = 5;
if(setsockopt(i16Sockfd, IPPROTO_TCP, TCP_KEEPCNT, amp;i16Maxcount, sizeof(i16Maxcount)) == -1){
perror("Maxcount");
}
}
int main()
{
struct sockaddr_in their_addr;
if ((i16Sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
perror("socket");
}
Enablekeepalive(i16Sockfd);
their_addr.sin_family = AF_INET; /* host byte order */
their_addr.sin_port = htons(PORT); /* short, network byte order */
their_addr.sin_addr.s_addr = inet_addr(SERVER_ADDRESS);
zero(amp;(their_addr.sin_zero), 8); /* zero the rest of the struct */
if (connect(i16Sockfd, (struct sockaddr*) amp;their_addr,sizeof(struct sockaddr)) == -1) {
perror("connect");
close(i16Sockfd);
}
}
Я не могу понять, почему он выдает недопустимый аргумент для всех setsockopt API. Есть ли что-то неправильное в настройке опции keep alive с помощью setsockopt?
Комментарии:
1. Почему вы используете
int16_t
для всех мест, требующихint
? Вероятно, они не одинакового размера в вашей системе.
Ответ №1:
SO_KEEPALIVE предназначен для сокета, ориентированного на соединение. Поэтому, пожалуйста, сначала подключите свой сокет и после этого установите SO_KEEPALIVE.
Комментарии:
1. У меня есть еще один вопрос: если я включил keep alive и установил все опции для keep alive, используя приведенный выше код, тогда мне нужно изменить настройки ниже? # echo 600 > /proc/sys /net/ipv4/tcp_keepalive_time # echo 60 > / proc /sys /net/ipv4 /tcp_keepalive_intvl # echo 20 > /proc /sys /net/ipv4/tcp_keepalive_probes
2. @AbhishekLakhara: Вам не нужно изменять настройки, если вы можете жить с текущими настройками. Обратите внимание, что вы также можете применить настройки, зависящие от сокета, для таймингов keep alive — см. tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/#setsockopt
Ответ №2:
Из socket(7)
документации, которая охватывает SO_XXX
параметры сокета:
Перечисленные ниже параметры сокета можно установить с помощью
setsockopt(2)
и считыватьgetsockopt(2)
с помощью уровня сокета, установленногоSOL_SOCKET
для всех сокетов. Если не указано иное,optval
является указателем на int .
и
SO_KEEPALIVE
Включить отправку сообщений keep-alive на сокетах, ориентированных на подключение. Ожидает целочисленный логический флаг.
Параметры и TCP_KEEPIDLE
т. Д., Специфичные для Linux, Также ожидают int
аргумент.
int16_t
Подобный, который вы используете в качестве типа параметра, вряд ли будет того же размера, int
что и в обычных системах в наши дни, отсюда и ошибки. Используйте int
вместо этого.