
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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
VB6‥ソケットについて
Visual Basic(VBA)
-
winsock通信時エラーの回避
Visual Basic(VBA)
-
WinsockコントロールのErrorイベントでオーバーフロー
Visual Basic(VBA)
-
-
4
VB6でユーザー定義型がNothingかどうか調べるには?
Visual Basic(VBA)
-
5
ネットワークでの受信バイト数
Visual Basic(VBA)
-
6
Winsockで接続待ちタイムアウトを設定する方法
C言語・C++・C#
-
7
Winsock 受信について
Visual Basic(VBA)
-
8
VB6で配列を文字列に変換する方法?
Visual Basic(VBA)
-
9
Winsockで1460Byte以降のデータが細切れに
Visual Basic(VBA)
-
10
VB6 配列を初期化したい
Visual Basic(VBA)
-
11
ExcelVBAでのwinsockの利用
その他(Microsoft Office)
-
12
Winsockを使ってVBでチャットをつくっているのですが・・・
Visual Basic(VBA)
-
13
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
14
WinSockを使ってのプリンタ接続・データ送信
Visual Basic(VBA)
-
15
ソケットのクローズについて
C言語・C++・C#
-
16
regsvr32で登録された一覧を知りたい
UNIX・Linux
-
17
VBの画面サイズについて
Visual Basic(VBA)
-
18
なぜオーバーフローになるのでしょうか。
Visual Basic(VBA)
-
19
VB6.0でのバイナリデータの扱いについて
Visual Basic(VBA)
-
20
VB6からVB2010への変換について
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
VB6のwinsockでconnectできない
-
VB6‥ソケットについて
-
相手のIPアドレスを取得する方法
-
closeされたsocketへの動作につ...
-
ソケットのクローズについて
-
JavaによるXMLの送受信
-
ソケットを用いた1対多通信につ...
-
CreateFile関数でCOMポートが開...
-
Socket通信の0バイト受信について
-
Macターミナルで実行中のプログ...
-
タスクマネージャーのプロセス...
-
VBAの配列サイズとメモリに関して
-
スーパーのレジで並んでいたら...
-
VB6 コマンドボタン クリック...
-
家電製品の電力周波数を変える機械
-
64BitOSについて
-
VBA、UserFormを前面に出力して...
-
vb.netでEXCEL起動がうまくでき...
-
このレジの並び方は間違ってま...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
UDP通信する時に、相手にどうや...
-
UDP通信におけるbind関数について
-
エクセル VBA でのCOMポート...
-
ソケットのクローズについて
-
ソケットのrecvの戻り値が0
-
VB6のwinsockでconnectできない
-
Socket通信の0バイト受信について
-
recv関数でフリーズしてしまう
-
Winsockで接続待ちタイムアウト...
-
Connectエラーが出てしまう・・...
-
送信したデータの一部が文字化...
-
【ajax】 XMLHttpRequestオブジ...
-
ソケット通信
-
closeされたsocketへの動作につ...
-
wsdlからのサービス化を行い。
-
Cにおける通信プログラミングの...
-
UdpClient 送信元のIPアドレ...
-
非ブロッキングソケットのrecv...
-
ソケットを用いた1対多通信につ...
おすすめ情報