トップ回答者
Winsockで送信バッファの空き状況を確認する方法

質問
回答
-
レスつきませんね。もっと詳しい人がいると思いますが自分はこう考えます。
簡単に言ってしまえば「そんな事を知っても意味がない」ということです。
RS-232C等と違ってソケットは排他に使用することはできません。複数のアプリの共有資源であり、
残りバッファの問い合わせの直後に他のアプリが送信リクエストしてしまう可能性があるのです。
この後、戻された残りバッファ数通りの送信をリクエストしても、ソケットはエラーを戻すかもしれません。
これでは、自分の「リクエスト」の結果を見てから身の振り方を工夫しなければならないことに、
何の変わりもありませんよねぇ。
つまり、ソケットの送信は送信エラーになるまで送るしかないのであって、それが
ほとんど唯一の正しい使い方であると言えるのです。
すべての返信
-
レスつきませんね。もっと詳しい人がいると思いますが自分はこう考えます。
簡単に言ってしまえば「そんな事を知っても意味がない」ということです。
RS-232C等と違ってソケットは排他に使用することはできません。複数のアプリの共有資源であり、
残りバッファの問い合わせの直後に他のアプリが送信リクエストしてしまう可能性があるのです。
この後、戻された残りバッファ数通りの送信をリクエストしても、ソケットはエラーを戻すかもしれません。
これでは、自分の「リクエスト」の結果を見てから身の振り方を工夫しなければならないことに、
何の変わりもありませんよねぇ。
つまり、ソケットの送信は送信エラーになるまで送るしかないのであって、それが
ほとんど唯一の正しい使い方であると言えるのです。
-
getsockopt(),WSAIoctlを確認しました。以下のパラメータがあるようです。
SO_SNDBUFは"送信バッファの最大値"を返してくれますが、空きのバイト
数はわかりません。ちなみに自分の環境(WinXpSP2)では8192が返りました。
やはり"送信エラー"で判断するしかないようです。
・getsockopt()のパラメータ
SO_ACCEPTCONN
SO_BROADCAST
SO_BSP_STATE
SO_CONDITIONAL_ACCEPT
SO_CONNECT_TIME
SO_DEBUG
SO_DONTLINGER
SO_DONTROUTE
SO_ERROR
SO_EXCLUSIVEADDRUSE
SO_GROUP_ID
SO_GROUP_PRIORITY
SO_KEEPALIVE
SO_LINGER
SO_MAX_MSG_SIZE
SO_OOBINLINE
SO_PORT_SCALABILITY
SO_PROTOCOL_INFO
SO_RCVBUF
SO_REUSEADDR
SO_SNDBUF
SO_TYPE
PVD_CONFIG・WSAIoctlのパラメータ
SIO_ADDRESS_LIST_CHANGE
SIO_ADDRESS_LIST_QUERY
SIO_ASSOCIATE_HANDLE
SIO_BASE_HANDLE
SIO_BSP_HANDLE
SIO_BSP_HANDLE_SELECT
SIO_BSP_HANDLE_POLL
SIO_CHK_QOS
SIO_ENABLE_CIRCULAR_QUEUEING
SIO_FIND_ROUTE
SIO_FLUSH
SIO_GET_BROADCAST_ADDRESS
SIO_GET_EXTENSION_FUNCTION_POINTER
SIO_GET_GROUP_QOS
SIO_GET_INTERFACE_LIST
SIO_GET_INTERFACE_LIST_EX
SIO_GET_QOS
SIO_IDEAL_SEND_BACKLOG_CHANGE
SIO_IDEAL_SEND_BACKLOG_QUERY
SIO_KEEPALIVE_VALS
SIO_MULTIPOINT_LOOPBACK
SIO_MULTICAST_SCOPE
SIO_QUERY_RSS_SCALABILITY_INFO
SIO_QUERY_WFP_ALE_ENDPOINT_HANDLE
SIO_RCVALL
SIO_RCVALL_IGMPMCAST
SIO_RCVALL_MCAST
SIO_ROUTING_INTERFACE_CHANGE
SIO_ROUTING_INTERFACE_QUERY
SIO_SET_COMPATIBILITY_MODE
SIO_SET_GROUP_QOS
SIO_SET_QOS
SIO_TRANSLATE_HANDLE
SIO_UDP_CONNRESET -
>どちらかといえば帯域制御でしょうか。
>通信回線(ソケット)の実質帯域にあわせてデータ量を
>変更したいと考えています。「相手のレスポンスに依存するスピードで送信」
したいということになるのでしょうか。
もうご存知かもしれませんが、以下にWinSockの「比較的」詳しい説明があります。
初心者の章は飛ばして、4章あたりが参考になるかもしれません。
DDKを持っていれば、7章の「
WsControl()
内部解析 」は利用価値があるかもしれません。Winsock Programmer's FAQ http://www.kt.rim.or.jp/~ksk/wskfaq-ja/
-
「WsControl() 内部解析」は、"フックDLLを使って..."など難しいことばかりで
ついていけませんでした。"帯域制御"については、無線環境での使用から考えるようになりました。
無線LANでは電波状況によってスピードが変化するようです。特にFOMAでは「384kbpsから64kbpsまで変化する」ということを聞きました。
一応、「メッセージ長+データのパケットをTCPで送信する」と考えていますので
1パケットの送信でエラー(送信サイズが要求サイズよりも短い場合)、
パケットの途中から送信しなければならなくなります。(捨てるわけには行かない)送信バッファの空きがわかれば事前にデータ量を減らせると考えたのですが。。。
-
TFTPプロトコル http://dictionary.rbbtoday.com/Details/term2355.html で、UDPを使うという手もあるかもしれません。
最近あまりネットワーク関係をプログラムしていないので、記憶が曖昧ですが、TCP/IPパケットに比べUDPはかなり
小さかった記憶があります。 (結果的にトラフィックを下げることになると思います。)
通信信頼性はTFTPの簡単なプロトコルと、物理層のW-CDMA、無線LAN等の誤り訂正能力(あったかな?)に頼ったほうが良いかもしれません。
-
Winsockではありませんがiphlpapiを使えば輻輳ウィンドウの状態を確認する事が可能です。
サンプルはこちらのURL
http://msdn.microsoft.com/en-us/library/bb485738(VS.85).aspx