ssってあまりなじみないけどこの一個前の記事書きながら状態を見るのに使ってみた。Send-Q/Recv-Qの値がそれぞれ何を意味してるのかを調べてみた。
サーバアプリ
ネタバレするとsocketの状態次第でssの出力の意味は変わってくるらしい。listen状態の場合はSend-Qはsocketのbacklogの最大値でRecv-Qがユーザアプリにacceptされていないsynの数。establish状態の場合はそのままSend-Qは送信して相手側からackを受け取っていないデータサイズ(byte)でRecv-Qはその逆。
これ系の検証はCの方が良さそうな気がするけどpythonでも行けたのでこっちを使う。backlogやらacceptをアプリで制御できる感じの仕組み
import socket import time serversocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM) Host = socket.gethostname() port = 9999 serversocket.bind((Host, port)) serversocket.listen(16384) while True: clientsocket,addr = serversocket.accept() #pass
listen時にacceptをしない状態で実行
-bash-4.2# ss -antl | grep 9999 LISTEN 1 8192 192.168.1.15:9999 *:*
結果は上記。クライアントアプリ1個がaccept待ちになっている。Send-Qは16384を設定してるがカーネル側の設定で最大値以下の2の冪乗の最大になっている。
establish時にデータをユーザアプリが受け取らない
acceptは行うがその後何もしないアプリを書く。telnetで適当な文字列を送る(8文字くらい)
-bash-4.2# ss -ant | grep 9999 LISTEN 0 8192 192.168.1.15:9999 *:* ESTAB 0 0 192.168.1.15:29454 192.168.1.15:9999 ESTAB 10 0 192.168.1.15:9999 192.168.1.15:29454
sendした側はソケットバファにデータを書き込めたので0になっているが受信側が何もしないのでキューに残っている。8文字送ったはずだがデータは10バイト来ている。末尾の改行文字入れても1バイト余る。
謎の1バイト
サーバ側でprintするとキャリッジリターンの制御文字がいた。
data : b'aaaaaaaa\r\n', addr: ('192.168.1.15', 29740)
newlines - Why does telnet send CRLF when I press enter? - Super User
telnetの仕様っぽいけど良くわからない。。。