Lenne egy linuxos tcp server, amin szeretném ha mennének a tcp keepalive csomagok. Tesztként levettem a tcp_keepalive_time -ot 10-re.
A server el is indul, a kliens becsatlakozik, jon is syn, synack majd ack csomag, ezt követően 10 sec múlva egy ack pár, majd semmi, csak server bont 60 sec múlva.
Mit hagyhattam ki, hogy nem 10 sec-omként küld keepalive csomagot?
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) a socket-em
int optval=1;
socklen_t optlen = sizeof(optval);
setsockopt(server_socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen)
Így akarnám, hogy kuldjön keepalive csomagokat.
cat /proc/sys/net/ipv4/tcp_keepalive_time
10
sysctl -a
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 10
Nem tom hogy tovább.
17:35:57.255024 IP (tos 0x10, ttl 64, id 41267, offset 0, flags [DF], proto: TCP (6), length: 60) localhost.55140 > localhost.1111: S, cksum 0x5265 (correct), 2079415374:2079415374(0) win 32792
17:35:57.255024 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: TCP (6), length: 60) localhost.1111 > localhost.55140: S, cksum 0x5d44 (correct), 2068181171:2068181171(0) ack 2079415375 win 32768
17:35:57.255037 IP (tos 0x10, ttl 64, id 41268, offset 0, flags [DF], proto: TCP (6), length: 52) localhost.55140 > localhost.1111: ., cksum 0x4266 (correct), 1:1(0) ack 1 win 1025
17:36:07.250364 IP (tos 0x0, ttl 64, id 3529, offset 0, flags [DF], proto: TCP (6), length: 52) localhost.1111 > localhost.55140: ., cksum 0x3e80 (correct), 0:0(0) ack 1 win 1024
17:36:07.250375 IP (tos 0x10, ttl 64, id 41269, offset 0, flags [DF], proto: TCP (6), length: 52) localhost.55140 > localhost.1111: ., cksum 0x3e7e (correct), 1:1(0) ack 1 win 1025
17:36:57.262562 IP (tos 0x0, ttl 64, id 3530, offset 0, flags [DF], proto: TCP (6), length: 52) localhost.1111 > localhost.55140: F, cksum 0x270d (correct), 1:1(0) ack 1 win 1024
17:36:57.262733 IP (tos 0x10, ttl 64, id 41270, offset 0, flags [DF], proto: TCP (6), length: 52) localhost.55140 > localhost.1111: F, cksum 0x1382 (correct), 1:1(0) ack 2 win 1025
17:36:57.262752 IP (tos 0x0, ttl 64, id 3531, offset 0, flags [DF], proto: TCP (6), length: 52) localhost.1111 > localhost.55140: ., cksum 0x1383 (correct), 2:2(0) ack 2 win 1024
- 1416 megtekintés
Hozzászólások
Ezt érdemes elolvasni.
A fentiek alapján tehát ez az elvárható működés. Az tcp_keepalive_time által indítottat látod 10 másodpercnél, de a következő csak a kapcsolat létrejötte után 10+75 (time+n*intvl) másodpercnél lenne a tcp_keepalive_intvl-nak megfelelően, miközben 60-nál bontod a kapcsolatot.
"Mit hagyhattam ki, hogy nem 10 sec-omként küld keepalive csomagot?"
Az tcp_keepalive_intvl 10 másodpercre való beállítását.
Ez az egész rendszerre hatással van. A 4.2 szerint csak az adott socketre is beállíthatod.
Milyen verziójú a kernel?
A 2.6.23-nál már tcp_keepalive_time a periódus, és a tcp_keepalive_intvl csak akkor kap szerepet, ha a tcp_keepalive_time időn belül nem érkezett válasz. Ha még nem telt le a tcp_keepalive_probes, és beérkezik a válasz, újra visszaáll a tcp_keepalive_time-ra.
- A hozzászóláshoz be kell jelentkezni
Szuper, köszi. Teljesen kiokosodtam.
Egy két részt a fordító nem ismert ezeket definiáni kellett, bemásolom ide, ha valakit később érdekel megtalálja.
#define TCP_NODELAY 1 /* Don't delay send to coalesce packets */
#define TCP_MAXSEG 2 /* Set maximum segment size */
#define TCP_CORK 3 /* Control sending of partial frames */
#define TCP_KEEPIDLE 4 /* Start keeplives after this period */
#define TCP_KEEPINTVL 5 /* Interval between keepalives */
#define TCP_KEEPCNT 6 /* Number of keepalives before death */
#define TCP_SYNCNT 7 /* Number of SYN retransmits */
#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
#define TCP_INFO 11 /* Information about this connection. */
#define TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */
#define SOL_TCP 6 /* TCP level */
- A hozzászóláshoz be kell jelentkezni
Találkoztam már olyannal, hogy így működött a keepalive:
(Lehet, hogy BSD rendszer volt, nem Linux, most tényleg nem emlékszem.
Egy próbát megér.)
char optval='1';
socklen_t optlen = sizeof(optval);
setsockopt(server_socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen)
- A hozzászóláshoz be kell jelentkezni