Winsockを使用してTCP/IP通信を行おうとしています。
複数端末を全て常にサーバーとして待ち受け状態にしておいて、
情報を送信するイベントが呼ばれたら
①クライアントとして接続要求し、②データ送信し、③切断する
という処理を行いたいのです。
これを別々のコマンドボタンからの処理にすると成功しましたが、
1クリックで全て行おうとすると、②のデータ送信時にエラーが出ます。
しかし、デバッグ状態でソースを変えずにそのまま進めると成功します。
または、②の直前にstopを入れてそのまま続けても成功します。
タイムラグが発生するのかと思い、②の前に5秒まで時間をあけてみましたが、
それは失敗でした。
次に、senddata処理をconnectイベントの中に入れてみましたところ、
エラーは出なくなったのですが、相手(サーバー)には
接続要求と切断の情報はいってるのですが、データは送信されませんでした。
サーバーのDataArrivalイベントは発生していないようです。
ここまでで対処のしようがなくなってしまったのですが、
どなたかご存知の方がいましたら、よろしくお願いします。
コードがまずいだけでしょう
コードはこのようになっています。
クライアントとしての処理のみ抜粋しています。
Dim wsListen, wsClient, wsServer As Winsock
Private Sub cmdSend_Click()
subClConnect
End Sub
Private Sub subClConnect()
If wsClient.State <> 0 Then
wsClient.Close
End If
wsClient.LocalPort = 0
wsClient.RemotePort = 10000
wsClient.Connect
End Sub
Private Sub axWinsockClient_Connect()
subClSend
axWinsockClient_Close
End Sub
Private Sub subClSend()
wsClient.SendData [txtMsg]
End Sub
Private Sub axWinsockClient_Close()
wsClient.Close
End Sub
Winsockコントロールの接続要求は、接続開始をOSに依頼し終わった時点でVBの処理に戻ってきます。
本当に接続が完了するのはもっと後です。
接続完了のイベントを拾うか、ループで接続完了まで待つべきです。
また、Winsockコントロールの接続要求はIDEでステップ実行するとイベント管理が狂うことがあるのでステップ実行には十分注意しましょう。
Set wsClient = axWinsockClient.Object
が抜けました。これはフォームロード時にセットしています。
ちゃんとイベントは拾っているのですね。となると
Connectイベントの中で送信していることが問題かもしれません。
一度Connectイベントプロシージャを終了してから送信を開始するために、
Timerコントロールを介して
Private Sub axWinsockClient_Connect()
tmrSend.Enabled = True
End Sub
Private Sub tmrSend_Timer()
tmrSend.Enabled = False
subClSend
axWinsockClient_Close
End Sub
としても駄目ですか?
コード自体コネクトのところに
ひろさんの言われるとおり、senddataしてすぐにclose処理してるのがどうかなぁとおもいますで
axWinsockClient_Close
はデータアライバルイベントあたりで処理したほうがいいと思います。
多分このプログラムでは連続して接続する仕様だとおもうのでその場合、
winsockコントロール自体にバグがあったので
こちらも確認してください。
http://support.microsoft.com/default.aspx?scid=kb;ja;245159
>Private Sub axWinsockClient_Connect()
> subClSend
> axWinsockClient_Close <-------------
>End Sub
これがまずいのでは?
送信し終わってないうちに切断している可能性があるよ
SendCompleteイベントで切断するべきでしょ
えーと、もしかして.NETでWinsockコントロールを使おうとしていますか?
.NETにはSystem.Net.Socketsがあるので、そちらを利用した方がいいと思います。
みなさま、ありがとうございました。
やはり送信が完了する前に切断命令がいってしまっていたようでした。
切断をSendCompleteイベントで行うことで解決しました。
バグの方も参照させていただきました。SPを当てます。
ツイート | ![]() |