
socketでconnectすると、sckclosingとなって通信できない。
機械との通信プログラムをつくるため、インターネットから以下のようなサンプルを取って、同一コンピュータ、または異なるコンピュータ間で通信しようとした(一部省略、改変)が、stateが8となってしまいます。socketを使うのは初めてで、皆目見当がつきません。よろしくお願いします。
サーバー側
Private Sub Form_Load()
Winsock1.LocalPort = 1001
Winsock1.Listen
--------
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim dat As String, ans As String
Dim n As Integer
Winsock1.GetData dat
Text1.Text = dat
Winsock1.SendData "わかりません"
End Sub
Private Sub Form_Load()
Text1.Text = "abc" (正しいコンピュータ名を入れた)
Winsock1.Close
LabCon.Caption = "Closed": LabCon.BackColor = vbWhite
End Sub
クライアント側
Private Sub Command1_Click()
Winsock1.Close
Winsock1.RemoteHost = Text1.Text
Winsock1.RemotePort = 1001 'ポート番号設定
Winsock1.Connect
Do While (Winsock1.State <> sckConnected)
LabCon.Caption = Winsock1.State
DoEvents
Loop
End Sub
クライアントでcommand1ボタンをクリックすると最初はstateが0、ループに入ると8となって出られません。WindowsXP、Vista共に同じ結果でした。
No.2ベストアンサー
- 回答日時:
確認させてください。
・サーバのコードはそれだけ?
Winsock_Accept()は作っていませんか?
8はsckClosingで、接続を相手が解除しようとしている状態です。
つまり、接続を受け付けるコードがないと接続を受け付けることができないので、切断されてしまいます。
Winsock_AcceptにrequireIdが渡されるので、それをAcceptしてください。
Winsock1.Accept requireId ←これで、サーバが接続を受け付けます
幾つか気がついたことを。
・LocalPortの初期化
バグと言うか、仕様なのですが、Connectするまえに、LocalPortを0クリアしてあげないと、二回目の接続がエラーになります。
RemotePort=1001の次の行にでも、いれてあげてください。
・なるべくWinsockのイベントハンドラを使う
一つのイベントに作り込んでループで待つと、通信が行われなかったり、ループとループの間の変化が捉えきれなかったりします。
今回のも、もしかすると、Winsock_Connectedを使っていれば、接続が解除されていたとわかったかもしれません。
(今はVB6の環境が無くなったので、かくにんできませんので、可能性の話なのですが)
たしか、SendDataが、Doeventをいれるか、イベントハンドラを終わらせないと、送信されないはずです。
(大分前の記憶なのでうろ覚えなのですが)
ご指摘の通りでした。ありがとうございます。
この通信は初めてで、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(変更可)です。是非これらの点も教えてください。
No.3
- 回答日時:
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で問題ありません。
補足の質問にまで答えていただき、ありがとうございました。
私は、新しいことを始めると、簡単なことでも、エラー情報等が出ていても、すぐにはその原因にたどり着けないことが多いです。今回は、ハードウエアも絡むのかなと思い、余計見当がつきませんでした。大変ありがとうございました。
また、今後、問題が出て、悩みそうなところも、丁寧に書いていただきありがとうございました。とりあえず、コンピュータ上でシュミレートが出来るレベルまでプログラミングができました。
No.1
- 回答日時:
Protocolプロパティを指定していない、ポート番号は正しいか?
このあたりが怪しいですね。
ついでながら繋がるまでループさせるのは良くないですね。
この回答への補足
早速にアドバイスありがとうございました。
Protocolプロパティは、入れても同じ結果でした。
ループは、上手く動かなかったのでそのようにしたまでです(当初はタイマー等をいれていました)。
ご指摘のポート番号は、全く理解していないので、インターネットのサンプルのままにしています。
目的の機械の番号は分かっているのですが、事前にコンピュータ上でシュミレートしたいと思っています。ポートの断片的な記述は見つかりましたが、理解するに至っていません。コンピュータの場合はどのように決めるのか、アドバイスまたは適当なサイトが有りましたらお教えください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- Excel(エクセル) マクロでテキストファイルを読み込んだ際の最終セルにデータと改行が含まれる問題の改善方法 2 2022/03/25 16:50
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Visual Basic(VBA) ①ExcelVBAでカレンダーを作り、別のユザーフォームで日付を入力したいのですがエラーになります。 1 2023/02/17 18:39
- Visual Basic(VBA) VBAで質問ですが、皆さんはどの様に導き出しているのでしょうか? 6 2022/05/03 21:53
- Visual Basic(VBA) 2つ目のコンボボックスが動作しません。 3 2023/03/25 12:29
- Visual Basic(VBA) 九九の答えの計算 3 2022/12/20 22:13
- Visual Basic(VBA) Excel VBA ユーザーフォーム1のコンボボックスに別ブックの値を反映させたいです。 6 2023/03/21 16:12
このQ&Aを見た人はこんなQ&Aも見ています
-
winsock通信時エラーの回避
Visual Basic(VBA)
-
VB6 配列を初期化したい
Visual Basic(VBA)
-
WinsockコントロールのErrorイベントでオーバーフロー
Visual Basic(VBA)
-
-
4
VB6‥ソケットについて
Visual Basic(VBA)
-
5
Winsockで接続待ちタイムアウトを設定する方法
C言語・C++・C#
-
6
VB6で配列を文字列に変換する方法?
Visual Basic(VBA)
-
7
ネットワークでの受信バイト数
Visual Basic(VBA)
-
8
VB6でユーザー定義型がNothingかどうか調べるには?
Visual Basic(VBA)
-
9
Winsock 受信について
Visual Basic(VBA)
-
10
WinSockを使ってのプリンタ接続・データ送信
Visual Basic(VBA)
-
11
Form_Load と Form_Activate のタイミング
Visual Basic(VBA)
-
12
VB6.0でのバイナリデータの扱いについて
Visual Basic(VBA)
-
13
VB6からVB2010への変換について
Visual Basic(VBA)
-
14
Loadイベント中にほかのイベントを発生したくない
その他(プログラミング・Web制作)
-
15
VB6(SP6)でのDoEventについて!
PowerPoint(パワーポイント)
-
16
FORMが開いているかどうかの確認方法
Visual Basic(VBA)
-
17
16進数の変換処理
Visual Basic(VBA)
-
18
VBの画面サイズについて
Visual Basic(VBA)
-
19
ソケット通信で同時受信の制限?
C言語・C++・C#
-
20
なぜオーバーフローになるのでしょうか。
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ソケットのクローズについて
-
ソケットを用いた1対多通信につ...
-
エクセル VBA でのCOMポート...
-
UDP通信する時に、相手にどうや...
-
Winsockを利用したファイルの送...
-
TCPによるファイル転送
-
Winsockで接続待ちタイムアウト...
-
ファイル転送が正常に動作しない
-
Socket通信を待ち受け状態にす...
-
closeされたsocketへの動作につ...
-
Macターミナルで実行中のプログ...
-
ウインドウにデータを入力する...
-
VBSでのSendKeysでの画面の最小化
-
C言語で、メモリを解放しないで...
-
逆コンパイルと逆アセンブルの...
-
PIC初心者です。 PIC16F88の...
-
C言語で途中までしか、プログラ...
-
イベントの発生から対応する処...
-
VC++スレッドの正しい終了のさ...
-
VB.NETでMessageBoxを表示した...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
UDP通信する時に、相手にどうや...
-
エクセル VBA でのCOMポート...
-
UDP通信におけるbind関数について
-
Winsockで接続待ちタイムアウト...
-
VB6のwinsockでconnectできない
-
ソケットのクローズについて
-
Connectエラーが出てしまう・・...
-
ソケットのrecvの戻り値が0
-
recv関数でフリーズしてしまう
-
CreateFile関数でCOMポートが開...
-
WinSockでの通信プログラムがう...
-
Socket通信の0バイト受信について
-
ソケット通信 同じポート番号...
-
空きポートの取得方法
-
MFCソケットについて
-
送信したデータの一部が文字化...
-
closeされたsocketへの動作につ...
-
ネットワークプログラミングに...
-
非ブロッキングソケットのrecv...
おすすめ情報