2012/04/04

python socket reset

明日こそは散髪に行こうと思っています!!

何がしたかったの? と聞かれてもマイッチングのですが
"python socket reset" で検索してました。
reset できるようになりたかったみたいです。
そんな質問には stackoverflow がさくっと答えてくれますよ

http://stackoverflow.com/questions/6439790/sending-a-reset-in-tcp-ip-socket-connection

SO_LINGER ってのを使えって書いてあるけど何じゃらほい。
ググるよ。

TCPメモ(Hishidama's TCP Memo)

ほー。SO_LINGER ってのを on で 0 に指定して close() しろと。
でも SO_LINGER って何じゃらほい? と思ってもう少し調べたけど、
結局 man に辿りついちゃうのよね。

Man page of SOCKET
SO_LINGER
SO_LINGER オプションを取得・設定する。引き数には linger 構造体を取る。
struct linger {
    int l_onoff;    /* linger active */
    int l_linger;   /* how many seconds to linger for */
};
有効になっていると、 close(2) や shutdown(2) は、そのソケットにキューイングされたメッセージがすべて送信完了するか、 linger (居残り) タイムアウトになるまで返らない。無効になっていると、 これらのコールはただちに戻り、クローズ動作はバックグラウンドで行われる。 ソケットのクローズを exit(2) の一部として行った場合には、残っているソケットの クローズ動作は必ずバックグラウンドに送られる。

  • SO_LINGER の設定無しに close とかすると後処理は kernel に任せられて SOCKET が何か WAIT になる
  • SO_LINGER が設定されてると TIMEOUT するか送信確認できるまで block する
  • 特に SO_LINGER が on で TIMEOUT が 0 だと

というわけでちょっと書いてみた:
import socket

addr = socket.getaddrinfo('www.google.com', 80)[0][4]
print(addr[0])
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, b'\1\0\0\0\0\0\0\0')
sock.connect(addr)
sock.close()
実行してみた:
$ time ip_address=`python test.py`; echo $ip_address; netstat -tn | grep "$ip_address"
74.125.235.81
何も残らない。TIMEOUT も 1 にしてみた:
import socket

addr = socket.getaddrinfo('www.google.com', 80)[0][4]
print(addr[0])
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, b'\1\0\0\0\1\0\0\0')
sock.connect(addr)
sock.close()
実行してみた:
$ ip_address=`python test.py`; echo $ip_address; netstat -tn | grep "$ip_address"
173.194.38.80
tcp        0      0 192.168.37.5:42359      173.194.38.80:80        TIME_WAIT  
残った。

TIMEOUT を設定すると RST じゃなくなる、のかな?
と思ったら違うか、TIMEOUT すると RST 投げるんだな、きっと。
ソース嫁ですと? ふへへ。

ちなみに、SO_LINGER で画像検索するとちょっと面白かったです。

2012/03/17

python ubuntu make LDFLAGS

Python Developers Festa 2012.03 に参加してきました。 日本オラクルのオフィスは相変らず素敵でした。 Python 3 の発表が 3 つくらいあったので再び少し興味を持ちました。 使ってみよう、3.3.0a1。 Ubuntu を用意して tar.bz2 を落として
sudo aptitude install gcc
sudo aptitude install make
make だ! っつーことで make してみたところ
Python build finished, but the necessary bits to build these modules were not found:
_bz2               _curses            _curses_panel
_dbm               _gdbm              _lzma
_sqlite3           _ssl               _tkinter
readline           zlib
To find the necessary bits, look in setup.py in detect_modules() for the module's name.


Failed to build these modules:
_crypt
なんてこと言われたんでこれは流石に困るなと思い 沢山 package 入れてみることに:
sudo aptitude install libbz2-dev
sudo aptitude install libncurses5-dev
sudo aptitude install liblzma-dev
sudo aptitude install libssl-dev
sudo aptitude install libreadline-dev
sudo aptitude install zlib1g-dev
sudo aptitude install g++
sudo aptitude install dpkg-dev
sudo aptitude install libsqlite3-dev
sudo aptitude install libgdbm-dev
よし、こんだけ入れればいいだろう! っと思って make してみたら何かやっぱダメ。 な、なんでや!! つわけでググってみたところ LiPyrary - Python for books: How to compile Python on Ubuntu 11.04 これか!
export arch=$(dpkg-architecture -qDEB_HOST_MULTIARCH)
export LDFLAGS="-L/usr/lib/$arch -L/lib/$arch"
export CFLAGS="-I/usr/include/$arch"
export CPPFLAGS="-I/usr/include/$arch"
したら無事に色々な library が読み込まれて module が使えるようになりました。 めでたしめでたし。