北海道に住みたいと言っているだけのブログ

Winsock2のUDPのsendto()におけるWSAEAFNOSUPPORT

これはハマった.
UDPで簡単なクライアントとサーバのメッセージ交換をするコードを書いたんだけど,クライアント側のsendto()でエラーが出る.
しかもにくいのは最初の一回はうまくいくんだけど二回目からエラーが出るという状況.
WSAGetLastError()でエラー番号を調べたらWSAEAFNOSUPPORT (10047) .
MicrosoftWindows ソケットのエラー コード、値、および意味
によると,「sendto (Wsapiref_4sqa.asp) などで適切でないファミリのアドレスがソケットに使用された場合、このエラーが返されます。」とあるけれど明らかに適切な使い方をしている(つもりだった).
そこで試行錯誤した結果,最終的に原因だったと思われたのがWSAStartup()にあった.
WSAStartup()はWinsockを使う前に必ず一度呼んでおかなければいけない関数.
もちろん原因のプログラムでも呼んではいたんだけど,これが違うスコープにあった.具体的には,スタートアップ関数(起動時に一度だけ呼ばれる)内でWSAStartup()を呼んで,別の関数でsocket()やら,sendto()やらを行ったからなのかなと.
だから,socket()する直前にもう一度WSAStartup()を入れたら見事に動いた.
WSAStartup()とUDP送信する関数の間では共有する変数がなかったから,てっきり別のスコープで行なっても良いのかと思ってたけど,ダメな時があるみたい.
特に10047番の症例がネット上にもほとんどなくて苦戦した.これが何かの役に立つことを祈りたい.無いか.
なお,WSAStartup()を複数回呼ぶのは問題ないらしいが,その際もWSACleanup()は一度でOK.


さて,帰ろう・・・