2012-02-09 17 views
1

NETLINK_ROUTEソケットからsocket.recv()を試して作成すると、利用可能なすべてのデータをrecvしないと、recvされていないデータが失われているようです。例えばPython Linux Netlink Recvバッファー

>>> import socket 
>>> sock = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, socket.NETLINK_ROUTE) 
>>> sock.bind((0,0)) 
>>> sock.send('\24\0\0\0\22\0\1\3\23\0364O\0\0\0\0\21\0\0\0') # struct nlmsghdr 
20 
>>> sock.recv(10000) 
'\xe4\x03\x00\x00 ... ' (+3000 more bytes) 

I sock.recv(100)場合は、100のバイトを返しますが、2900の他のバイトがなくなっています。別のsock.recv()を実行すると、次のnlmsghdr(マルチパートメッセージの場合)またはブロックしているデータが返されます。

sock.recv(X, socket.MSG_PEEK)は、データが失われることなくXバイトを読み取ることができます。しかし、それを行うときには、読み込まれたデータはもちろんrecvバッファからpop'dされません。

私は、読み込まれていないデータは、読み込むまでバッファに残っていると思っていました。私は間違って何をしていますか?私はむしろ、どのくらいのデータが利用可能であるかを「推測」したくないでしょう...

答えて

2

これは、データグラム(SOCK_DGRAMソケット)が機能する方法です。メッセージ境界は維持され、パケット全体を読み取らないと、破棄されます(SOCK_STREAMソケット、つまりTCPはすぐに必要なだけ多くのバイトを読み取ることができるバイトストリームサービスを提供し、残りはソケットバッファに保持されます)。

Netlinkはデータグラムサービスを提供しており、SOCK_DGRAMまたはSOCK_RAWソケットを使用できます。

問題点は何ですか? AFAIK netlinkにはメッセージサイズの上限がありますので、それを使ってメッセージを受信して​​ください。

+0

私はちょうどそのように動作するとは思わなかった。私はソケットバッファから一度に一つのnetlink msgを読むだけで構いませんでした。これが期待される振る舞い(それを変更するフラグがない)であれば、自分のバッファから作成して読み込むだけです。 – tMC

+0

私が知る限り、この動作を変更することはできません。メッセージを読む前に実際にメッセージの正確なサイズを知る必要がある場合は、nlmsghdrを見るとパケットの長さがわかります。 – ldx

+0

それは私の計画だった。問題は、単一のデータグラムに複数のメッセージが存在する可能性があることです。最初のパケットの 'nlmsg_len 'を読むことは同じデータグラムの他のmsgsのサイズを含んでいません。 – tMC

関連する問題