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)
-
VBの「As String * 128」とは?
Visual Basic(VBA)
-
-
4
TCP/IP通信時のサーバーからの受信
C言語・C++・C#
-
5
Visual Basic 6.0 コンボボックスのChangeイベントが発生しません
Visual Basic(VBA)
-
6
CloseとDisposeの違い
Visual Basic(VBA)
-
7
VB6のプロジェクトロードエラーについて
Visual Basic(VBA)
-
8
Winsockで接続待ちタイムアウトを設定する方法
C言語・C++・C#
-
9
VBのソケット通信(winsock)のサイト
Visual Basic(VBA)
-
10
VBプログラムの終了
Visual Basic(VBA)
-
11
VB6.0の「vbFromUnicode」はVB.NETではどれに相当しますか?
Visual Basic(VBA)
-
12
vb6で異なるのプロジェクト間で、値を渡したい
Visual Basic(VBA)
-
13
【VB6.0】 あるフォームから他のフォームへ値を受け渡したい
Visual Basic(VBA)
-
14
16進数の変換処理
Visual Basic(VBA)
-
15
Winsockを使ってVBでチャットをつくっているのですが・・・
Visual Basic(VBA)
-
16
VB6.0-整数と余りを求める
Visual Basic(VBA)
-
17
WinSockを使ってのプリンタ接続・データ送信
Visual Basic(VBA)
-
18
Shapeコントロールの.NET移行方法
Visual Basic(VBA)
-
19
VisualBasic6.0のFormat関数でmSecを表示したい
Visual Basic(VBA)
-
20
PLCとPCの通信
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ソケットプログラミングに関す...
-
Winsockで接続待ちタイムアウト...
-
TCP/IP通信時のサーバーからの受信
-
エクセル VBA でのCOMポート...
-
VB6のwinsockでconnectできない
-
ソケットのrecvの戻り値が0
-
ソケットのクローズについて
-
ソケットを用いた1対多通信につ...
-
相手のIPアドレスを取得する方法
-
Javaプログラム同士のプロセス...
-
VB6‥ソケットについて
-
SIPがNATを越えられない理由
-
vbでの232c接続プログラムについて
-
UdpClient 送信元のIPアドレ...
-
recv関数でフリーズしてしまう
-
ソケット通信 同じポート番号...
-
UDP通信する時に、相手にどうや...
-
c# ソケット非同期通信プログラム
-
異なる言語間でのソケット通信...
-
UDP通信におけるbind関数について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
recv関数でフリーズしてしまう
-
Winsockで接続待ちタイムアウト...
-
UDP通信におけるbind関数について
-
エクセル VBA でのCOMポート...
-
Socket通信の0バイト受信について
-
VB6のwinsockでconnectできない
-
ソケットのrecvの戻り値が0
-
ソケットを用いた1対多通信につ...
-
UdpClient 送信元のIPアドレ...
-
ソケットでクライアントのipア...
-
UDP通信する時に、相手にどうや...
-
ソケット通信 同じポート番号...
-
同じLAN内パソコンのIPアドレス...
-
Connectエラーが出てしまう・・...
-
ソケットのクローズについて
-
CreateFile関数でCOMポートが開...
-
異なる言語間でのソケット通信...
-
C言語でHTTP1.1のキープアライ...
-
送信したデータの一部が文字化...
おすすめ情報