地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Linux】ssコマンドのSend-Q/Recv-Q

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をしない状態で実行

acceptをコメントアウトしてtelnetで接続。

-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の仕様っぽいけど良くわからない。。。