- ベストアンサー
VB6のwinsockでconnectできない
- socketでconnectすると、sckclosingとなって通信できない
- 機械との通信プログラムをつくるため、インターネットから以下のようなサンプルを取って、同一コンピュータ、または異なるコンピュータ間で通信しようとしたが、stateが8となってしまいます
- socketを使うのは初めてで、皆目見当がつきません
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
確認させてください。 ・サーバのコードはそれだけ? Winsock_Accept()は作っていませんか? 8はsckClosingで、接続を相手が解除しようとしている状態です。 つまり、接続を受け付けるコードがないと接続を受け付けることができないので、切断されてしまいます。 Winsock_AcceptにrequireIdが渡されるので、それをAcceptしてください。 Winsock1.Accept requireId ←これで、サーバが接続を受け付けます 幾つか気がついたことを。 ・LocalPortの初期化 バグと言うか、仕様なのですが、Connectするまえに、LocalPortを0クリアしてあげないと、二回目の接続がエラーになります。 RemotePort=1001の次の行にでも、いれてあげてください。 ・なるべくWinsockのイベントハンドラを使う 一つのイベントに作り込んでループで待つと、通信が行われなかったり、ループとループの間の変化が捉えきれなかったりします。 今回のも、もしかすると、Winsock_Connectedを使っていれば、接続が解除されていたとわかったかもしれません。 (今はVB6の環境が無くなったので、かくにんできませんので、可能性の話なのですが) たしか、SendDataが、Doeventをいれるか、イベントハンドラを終わらせないと、送信されないはずです。 (大分前の記憶なのでうろ覚えなのですが)
その他の回答 (2)
- unacyo
- ベストアンサー率51% (35/68)
ANo.2です。 ・Connectの後はSendData/RecvDataで良いか? そうなります。 ただ、注意しなければならないのは、TCPIPは一度に転送される最小バイト数が1バイトなので、少ないデータ量ならばあまり問題になりませんが、大きいデータの場合一度の受信で全部受信されません。 特にMTUを変更していなければ、通常は1460バイトを越えたあたりから、工夫が必要になります。 わたしは、この辺りを実装するのが面倒なので、Connectイベントでファイルを開き、DataAvaivalイベントで書き込んでいます。 コマンド発行/応答受信の場合は、受信データをファイルに書き込んだ後に終端文字CRLFやETX等があるか確認し、あった場合はファイルを閉じて読みこみ、解析します。 通信が全て終わったら、Closeをすればよいです。しかし、次の通信開始は、Closedイベントが発生するのを待ってください。 ・RemotePortとLocalPortについて RemotePortは、いうなれば、代表電話番号みたいなものなので、基本的に器機が指定するポートを使えば良いです。器機側のポート番号は、特別な理由がなければ、変えない方が良いでしょう。 LocalPortは、指定されていなければ、0指定でokです。 クライアント側のポート番号を固定にしてしまうと、このツールを複数立ち上げれなくなります。 (器機側が複数の接続に対応していることも必要ですが) 0指定は、実際には1025~2048のポートのうち、空いているポートをOSが割り当ててくれます。 接続先の器機が、クライアントのポートを指定しているのであればその番号を、そうでなければ0で問題ありません。
お礼
補足の質問にまで答えていただき、ありがとうございました。 私は、新しいことを始めると、簡単なことでも、エラー情報等が出ていても、すぐにはその原因にたどり着けないことが多いです。今回は、ハードウエアも絡むのかなと思い、余計見当がつきませんでした。大変ありがとうございました。 また、今後、問題が出て、悩みそうなところも、丁寧に書いていただきありがとうございました。とりあえず、コンピュータ上でシュミレートが出来るレベルまでプログラミングができました。
- TooManyBugs
- ベストアンサー率27% (1472/5321)
Protocolプロパティを指定していない、ポート番号は正しいか? このあたりが怪しいですね。 ついでながら繋がるまでループさせるのは良くないですね。
補足
早速にアドバイスありがとうございました。 Protocolプロパティは、入れても同じ結果でした。 ループは、上手く動かなかったのでそのようにしたまでです(当初はタイマー等をいれていました)。 ご指摘のポート番号は、全く理解していないので、インターネットのサンプルのままにしています。 目的の機械の番号は分かっているのですが、事前にコンピュータ上でシュミレートしたいと思っています。ポートの断片的な記述は見つかりましたが、理解するに至っていません。コンピュータの場合はどのように決めるのか、アドバイスまたは適当なサイトが有りましたらお教えください。
お礼
ご指摘の通りでした。ありがとうございます。 この通信は初めてで、Listenをして、DataArraivalで受ければいいのかと思っていましたので、以下の処理があることを見落としていました。 Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long) If Winsock1.State <> sckClosed Then 'Winsockの状態(閉じていない) Winsock1.Close 'Winsockを閉じる End If Winsock1.Accept requestID '接続処理 End Sub ところで、一度connectすると、SendDataとGetDataを繰り返して、最後にcloseしてよいのですか。また、多くのサンプルでLocarPortとRemotePortが同じ番号が使われていますが、このようにするものですか。また、この番号は任意でよいのですか。目的の機械は4444(変更可)です。是非これらの点も教えてください。