winsock通信時エラーの回避

このQ&Aのポイント
  • winsock通信でデータを送受信する際に発生するエラーを回避する方法について教えてください。
  • 質問の整理ですが、winsock通信でサーバー側が通信エラーのため止まってしまう問題が発生しています。解決策を教えてください。
  • winsock通信のエラーを起こした通信を破棄しても良い方法や、Winsock1_Errorコードの修正方法について教えてください。
回答を見る
  • ベストアンサー

winsock通信時エラーの回避

winsock通信でデータをクライアント側からサーバー側に送り、一定の条件でサーバー側からクライアント側にデータを戻すソフトを作成中なのですが、サーバー側が通信エラーの為か止まってしまいます。 サーバー側(winsock部分)記述 Private Sub Winsock1_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) Winsock1(Index).Close '接続を閉じる Do While Not (Winsock1(Index).State = sckClosed) DoEvents Loop On Error Resume Next Winsock1(Index).Listen If Winsock1(Index).LocalPort <> 0 Then Winsock1(Index).LocalPort = 0 End If End Sub 質問の整理ですが、 表示板にはギミックが付いておりそのギミックは止まらないのでパソコンのフリーズでは無い様子です。 で問題は通信部分だと推測されるのですが、そのエラーを起こした通信を破棄してもいいので、サーバー側の点数加算を止めない方法はありませんでしょうか。 また上記のWinsock1_Errorコードの記述じゃおかしいのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

現象が発生するのはまれでしょうか? 試してみましたがクライアントから連続してconnectすると発生しやすいようです。 ただ、このエラーが発生しても、特に異常が見られないので、このエラーを無視してはどうでしょうか? Private Sub Winsock1_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) If Index = 0 Then ' 受け付けるポートと接続するポートは処理が違う If Number <> 10035 Then ' エラーコード10035は、無視 Winsock1(Index).Close '接続を閉じる Do While Not (Winsock1(Index).State = sckClosed) DoEvents Loop On Error Resume Next Winsock1(Index).Listen End If Else Winsock1(Index).Close '接続を閉じる Do While Not (Winsock1(Index).State = sckClosed) DoEvents Loop Unload Winsock1(Index) closedSocks.Add Index End If End Sub

mado2000
質問者

お礼

返答遅くなり、申し訳ございません。 エラーだからといって、回避ばかりでなく無視する方法もあるのですね。 たいへん勉強になりました。 また、質問を書き込みした時は、よろしくお願いします。

その他の回答 (4)

回答No.4

障害を切り分けるために、追加したところをはずすと 32767回までは、ちゃんと動くのですか? ちゃんと動くのであれば、追加したコントロールを再利用する ところにおかしいところがあるのではないかと思います。

回答No.3

ConnectionRequestイベントを単純に以下のようにするとどうなりますか? Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)   If Index = 0 Then     sockNum = sockNum + 1     Load Winsock1(sockNum)     Winsock1(sockNum).LocalPort = 0     Winsock1(sockNum).Accept requestID   End If End Sub

mado2000
質問者

補足

毎日お世話になります。 以前の状態ではいただいたソースのまま書いていたのですが、IndexがIntegerなので、32767回の通信でオーバーフローを起こしていた為、今回のソースに書き直したしだいです。これは先日この投稿掲示板に配列について私自身が質問して、教えていただいたもので http://oshiete1.goo.ne.jp/qa2440588.html リンクに詳細があります。

回答No.2

1.エラーイベントの以下を削除するとどうなりますか? On Error Resume Next Winsock1(Index).Listen If Winsock1(Index).LocalPort <> 0 Then Winsock1(Index).LocalPort = 0 2.何をやったときに、エラーが発生しますか? 3.クライアント側の状態はどうなっていますか?  エラーが出ているとか、その場合はエラーの内容は?

mado2000
質問者

補足

連日の投稿ありがとうございます。 1.エラーイベント以下を削除すると、サーバー側の数字は加算されず止まったままの状態です。 2.最初の一対一の場合は問題ないのですが、2台目や3台目になると止まってしまいます。 3.クライアントは一切エラーは出ません。 エラーを表示させるようにしたら、どうもソケットの処理が終わらないのに、データが来るのが問題のようですが、今日も1日ネットを調べてもそこら辺が理解できずにいます。 また、ご指導お願いします。

回答No.1

状況、質問内容がよくわかりません。 >サーバー側が通信エラーの為か止まってしまいます。 「通信エラーの為か」って、まず通信エラーが発生しているのかどうかもわかっていない?止まるとはどういう状態?  Winsock1_Errorイベントの最初で、Number とDescription をメッセージボックスなどに表示すればどういうエラーが発生しているのか、あるいは、エラーが発生していないのかわかると思いますが。 >On Error Resume Next  エラーを無視しているだけで後でエラーをチェックしていないので、エラーが発生していてもわからない。これを取るとどうなりますか? >また上記のWinsock1_Errorコードの記述じゃおかしいのでしょうか。  各クライアント用に、サーバのポートを分けているのでしょうか。  Winsockコントロールで、サーバ側のプログラムを作る場合は、VB6.0のSP4以降は必須です。古いバージョンのOCXは、使い物になりません。

mado2000
質問者

補足

補足要求ありがとうございます。質問の字数制限で上記までしか書けなかったのですが、ゲームを作成していて、サーバー1台に対し10台のクライアントがくっついています。クライアントがゲームをすると、サーバーに点数がアップされ、ゲームに勝つとその中の一部がが払いだされる仕組みになっています。サーバーソフトにはLabelを貼り付け、点数を加算しているのですが、その加算が止まってしまいます。 ご指摘通りにまずVBのSPを確認したところSP2でしたので,SP5にバージョンアップしました。その次にどんなエラーが発生しているか確認を記述したところ、Index0 エラーNo.10035 ソケットはブロッキングを行いません。指定した処理がブロッキングを行います。と表示されました。ずっとブロッキングについて調べているのですが、今のところどのようにしたら良いかわかっておらず、困っております。 On Error Resume Nextについては、取っても変化無く同じ表示を繰り返します。またTCP接続にしているため特にポートの振り分けはしていません。 Private Sub Form_Load() Set closedSocks = New Collection   Winsock1.Item(0).LocalPort = 1001 Winsock1.Item(0).Listen End Sub Private Sub Winsock1_Close(Index As Integer)   Unload Winsock1(Index) closedSocks.Add Index End Sub Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)   If Index = 0 Then Dim connectsocknum As Integer If closedSocks.Count > 0 Then connectsocknum = closedSocks.Item(1) closedSocks.Remove 1 Text1.Text = sockNum Text9.Text = closedSocks.Count Else sockNum = sockNum + 1 connectsocknum = sockNum   End If Load Winsock1(connectsocknum) Winsock1(connectsocknum).LocalPort = 0 Winsock1.Item(connectsocknum).Accept requestID End If End Sub Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long) Winsock1(Index).GetData dat n = dat If n = 1 Then Label1.Caption = Label1.Caption + 10 y = 1 ans = y Winsock1.Item(Index).SendData ans 中略 ElseIf n = 7 Then ans = Label1.Caption Winsock1.Item(Index).SendData ans Label1.Caption = 0 End If End Sub 以上がWinsockのほとんどです。変数の指定や今回質問に入れたエラー部分は入って降りません。初めて作ったソフトのため変数の使い方などがおかしいとかサンプルのまんまとかありますが、またご指導いただける様お願いいたします。

関連するQ&A

  • VB6のwinsockでconnectできない

    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共に同じ結果でした。

  • winsockの配列(1対多数のプログラム)

    お世話になります。VBで1対多数の通信プログラムを作っているのですが、受けて側をConnectionRequest のプロシージャで If Index = 0 Then sockNum = sockNum + 1 Load Winsock1(sockNum) Winsock1(sockNum).LocalPort = 0 Winsock1(sockNum).Accept requestID としてコントロール配列をさせています。 通信は問題ないのですが、WinsockのIndexがIntegerの上限まできたら、オーバーフローを起こします。 リセット、もしくは回避の方法がまったくわからず困っています。どうぞお力お貸しください。

  • 現在WINSOCKコントロールを用いて通信プログラムを作成しています

    現在WINSOCKコントロールを用いて通信プログラムを作成しています サーバ側の設定が IP:192.168.1.10 Port:10000のとき、 Winsock.state = 7(Listen状態) クライアント側で Winsock.Close Winsock.RemoteHost = "192.168.1.10" Winsock.RemotePort = 10000 Winsock.Connect で実行したときにエラー10061で返ってきます。 NETSTAT -anで他にこのポートを使用ものは有りませんでした どのようにすればエラーが回避できますでしょうか?

  • winsockを使った通信方法

    winsockを使った通信でサーバークライアント方式の通信プログラムで クライアントプログラムがサーバープログラムに接続して、 クライアントプログラムで移動あった時のみ サーバーに現在の位置情報を送信し、サーバープログラムが他の参加者に 送信するという通信方式で通信を行っています。 この方法だと接続者が複数人の場合、一人だけ移動していると普通に通信でき位置情報の更新 も出来るのですが、 同時に移動が起こると、モデルが勝手に移動してクライアントプログラムに触れなくなってしまいます。 これを避けるにはどうしたらいいでしょうか?

  • VB6.0 Winsockについての質問です。

    VB6.0 Winsockについての質問です。 はじめまして。 現在、VB6.0を使用してTCP通信にてテキストデータを送るプログラムを作成しています。 機能としては全て完成しているのですが、現在再接続ができないじょうたいです。 PC上にサーバプログラムとクライアントプログラムを立ち上げます。 localport は 0 として設定しており、 host は、localhostとしています。 remortportは5000を設定しております。 現段階で発生している問題として、 クライアント側にてConnectイベントをさせ、 サーバ側にて、ConnectionRequestイベントが発生します。 クライアント側にて、Closeイベントは発生させ、 サーバー側も切断を確認します。 この状態でクライアント側から再度Connectイベントを発生させても サーバ側にてConnectionRequestイベントが発生しません。 サーバ側のプログラム一度終了させ、もう一度起動させると また、接続が可能になります。 もう、2日以上悩んでいるのですが、、、解決できません。 どなたか、詳しい方がいらっしゃいましたらご教授お願いします。

  • Winsockを利用したファイルの送受信について

    こんにちは。現在、VisualBasicでwinsockを利用して jpg画像の転送をやりたいと思っているのですが、うまくいきません。 制御用のプログラムなのでjpg画像は2分割して送ります。 ちょっと汚いソースで申し訳ないのですが、クライアント側は以下のようになってます。ソケット1で通信の制御信号を送受信して、ソケット2で実際の画像データを送信します。画像は2分割にして送ります。 Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim sSend As String Dim buffer() As Byte Dim lSendSize As Long Winsock1.GetData buf, vbString, bytesTotal Select Case buf Case SIG_REQUESTIMAGE     f = FreeFile sFile = "send.jpg" Open sFile For Binary As #f lFileSize = LOF(f) sSend = CStr(lFileSize) Winsock1.SendData sSend DoEvents Case "reciv_size" '画像サイズ受信確認信号1       lSendSize = lFileSize - 1 l1SendSize = lSendSize / 2 l2SendSize = lSendSize - l1SendSize ReDim buffer1(l1SendSize) ReDim buffer2(l2SendSize) Get #f, , buffer1       sCommand = CStr(buffer1) Get #f, , buffer2 Winsock2.SendData sCommand  Case "reciv1" '画像サイズ受信確認信号2 sCommand = CStr(buffer2)       Winsock2.SendData sCommand       Close #f

  • RegQueryValueExwでエラー

    お世話になります。 Declare Function RegQueryValueExString Lib "advapi32.dll" Alias _ "RegQueryValueExA"(ByVal hKey As Integer, ByVal lpValueName As String, ByVal lpReserved As Integer, ByRef lpType As Integer, ByVal lpData As String, ByRef lpcbData As Integer) As Integer RegQueryValueExString(hKey, ValueName, 0, intType, strValue, intSize) この時、ValueNameに2バイト文字が含まれているとエラーになります。 VB 6.0の時は問題なく動いていました。 ご存知の方ご教示お願いいたします。

  • Visual Basic.NETのエラー("オブジェクト参照がオブジェクト インスタンスに設定されていません。")について

    DLLを読み込むプログラムで、以下のように宣言した関数"VCread_wave_file"を呼び出そうとすると、 "オブジェクト参照がオブジェクト インスタンスに設定されていません。" というエラーが出てしまうのですが、なぜなのでしょうか? プログラムは以下のようになっています。 Public Class Form1 Inherits System.Windows.Forms.Form Dim status As Integer Dim wavelength As Long Dim samplf As Double Private Declare Function VCread_wave_file Lib "Vcon.dll" (ByVal FileName As String, ByVal tmpFilename As String, ByVal wavelength As Long, ByVal samplingFrequency As Double) As Integer (中略) Private Sub ChangeStartButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ChangeStartButton.Click status = VCread_wave_file("rectmp.wav", "rectmp.raw", wavelength, samplf) Label4.Text = status End Sub よろしくお願いいたします。

  • WinsockによるUDP通信にて

    WinsockでUDP通信を行うプログラムを作っているのですが、 原因不明の問題が発生していて困っています。 通信手順は以下のとおりです。 (1) クライアントからサーバへ要求パケット送信 (2) 要求パケットを受け取ったサーバは、クライアントへACKを送信 (3) サーバが要求に対する応答パケットをクライアントへ送信 (4) 応答パケットを受け取ったクライアントは、サーバへACKを送信 クライアント-サーバ間でやりとりするデータは最大で992バイト、 それ以上になる場合は、分割して送信します。 パケットの分割が発生しない場合は、(1)~(3)がパケットの損失もなく通信できるのですが、 パケットの分割が発生する場合には、2回目以降の(4)のパケットがクライアントに届きません。再現率は今のところ100%です。 クライアント側のselect関数でもソケットを検出しません。 たしかにUDPは信頼性が低いですが、パケット分割が発生しないパターンでは100%届くので、UDPの仕様とは関係ないような気がします。 原因がさっぱりわからないので、アドバイスをお願いいたします。 ちなみに、クライアント、サーバともに同一端末内にあります(双方がループバックアドレスに対してパケットを送信)が、 これはテスト段階だからであって、本来はそれぞれ別々の端末で動作します。

  • winsockについて

    winsock、非同期モードでTCP/IP通信を行うようなプログラムを作成しています。 通常の同期モードでのプログラムは完成させることができました。 そこで、クライアント側を非同期モードにし、受信バッファにデータが入ったら受信するというようなプログラムにしたのですが、どうもうまく動作してくれません。 やはりサーバー側も非同期モードにしなければならないのですか?? どなたかご教授お願いします。

専門家に質問してみよう