[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/02/23(Wed) 13:38
投稿者名:yuta
Eメール:
URL :
タイトル:
Winsockコンポーネント(切断後の再接続)
こんにちは、いつもこちらのサイトを参考にさせていただいてます。

早速ですが質問があります。

現在、WinSockコンポーネントを使って、複数のクライアントと接続可能なTCP/IPサーバを作成してい
ます。(VB Enterprise 6.0のSP5です。)

MSDNライブラリを参考にして、複数のクライアントとの接続とデータの送受信はできるようになった
のですが、クライアントの再接続時に「すでにメモリがロードされています。」というエラーが発生
してしまいます。

その後、Closeイベントなどをいろいろデバッグをしてみたのですが、他に接続しているクライアント
の接続が終了してしまったりと、うまくいきませんでした。

どなたかご存知の方がいらっしゃればご教授お願いします。
(下にソースコードを記述しておきます。)
-------------------------------------------------------------------------------------------
※tcpServer      …Winsockコンポーネント(Indexプロパティを0に設定。)
※intConnectMax  …接続中のクライアントの数(モジュールレベルで宣言)
※Listenなどのイベントは省略しています。

Private Sub tcpServer_Close(Index As Integer)  
'接続が切断された
tcpServer(Index).Close                   '接続しているサーバを閉じる
intConnectMax = intConnectMax - 1        '接続クライアント数を1台分減らす。
Unload tcpServer(intConnectMax)          '使用していたコンポーネントを開放する

End Sub
-------------------------------------------------------------------------------------------
Private Sub tcpServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    
    '接続要求がきたとき,相手アプリからの接続要求を受け付ける
    If Index = 0 Then
        intConnectMax = intConnectMax + 1               '接続クライアントの数を一台増やす
        Load tcpServer(intConnectMax)                   '接続要求のあったクライアント用
                                                        'サーバコントロールをロードする
        tcpServer(intConnectMax).Accept requestID       'クライアントとの接続を受け入れる
   End If
End Sub
-------------------------------------------------------------------------------------------
以上です、長文失礼しました。 m(_ _)m

投稿時間:2005/02/23(Wed) 13:55
投稿者名:フォレスト
Eメール:
URL :
タイトル:
Re: Winsockコンポーネント(切断後の再接続)
> その後、Closeイベントなどをいろいろデバッグをしてみたのですが、他に接続しているクライアン

> の接続が終了してしまったりと、うまくいきませんでした。

その原因は以下の所だと。

> Private Sub tcpServer_Close(Index As Integer)  
> '接続が切断された
> tcpServer(Index).Close                   '接続しているサーバを閉じる
> intConnectMax = intConnectMax - 1        '接続クライアント数を1台分減らす。
> Unload tcpServer(intConnectMax)          '使用していたコンポーネントを開放する
>
> End Sub

UnloadするコンポーネントインデックスはintConnectMax?
Indexじゃなくて?

例えば5台繋いでいるとして、3台目のクライアントが接続要求を出してくるとします。
CloseするのはIndexの値なので3台目ですが、UnloadするのはintConnectMaxつまり、
5台目をUnloadしてしまうんじゃないかと思います。

あまりWinSock使ったことないですけど、コードを見るとココかな?

投稿時間:2005/02/23(Wed) 14:53
投稿者名:yuta
Eメール:
URL :
タイトル:
Re^2: Winsockコンポーネント(切断後の再接続)
早速のレス、ありがとうございます。
> その原因は以下の所だと。
>
> > Unload tcpServer(intConnectMax)          '使用していたコンポーネントを開放する
>
> UnloadするコンポーネントインデックスはintConnectMax?
> Indexじゃなくて?
先ほどIndexにして実行してみたところ、ConnectionRequestイベントで、
"このオブジェクトは、すでにロードされています。"というエラーが出てしまいました。

原因としては、intConnectionMaxの値のインクリメントのタイミングだと思うのですが、タイミングを
変えたとしても、同じような結果になってしまいました。

自分でも解決法を探していますが、他にご存知の方がいらっしゃいましたらご教授のほどをお願いしま
す。

投稿時間:2005/02/23(Wed) 15:04
投稿者名:フォレスト
Eメール:
URL :
タイトル:
Re^3: Winsockコンポーネント(切断後の再接続)
> 先ほどIndexにして実行してみたところ、ConnectionRequestイベントで、
> "このオブジェクトは、すでにロードされています。"というエラーが出てしまいました

>
> 原因としては、intConnectionMaxの値のインクリメントのタイミングだと思うのですが、タイミン
グを
> 変えたとしても、同じような結果になってしまいました。
>
> 自分でも解決法を探していますが、他にご存知の方がいらっしゃいましたらご教授のほどをお願い
しま
> す。

ConnectionRequestの
tcpServer(intConnectMax).Accept requestID
も、Indexに変える必要あり?

投稿時間:2005/02/23(Wed) 15:33
投稿者名:yuta
Eメール:
URL :
タイトル:
Re^4: Winsockコンポーネント(切断後の再接続)
> ConnectionRequestの
> tcpServer(intConnectMax).Accept requestID
> も、Indexに変える必要あり?

説明不足でした、すいません。

ConnectionRequestイベントで取得できるIndex値は、リスニングコントロールとして使用されているの
で、常に0で返ってきます。
(詳しい説明は、MSDNライブラリの[WinSockコントロールの使い方]の[二つ以上の接続要求の受け付け]
に記載されています。)

投稿時間:2005/02/23(Wed) 16:36
投稿者名:yuta
Eメール:
URL :
タイトル:
[解決]: Winsockコンポーネント(切断後の再接続)
あれからいろいろと方法を模索した結果、以下のソースで正常に動作しました!!

---------------------------------------------------------------------------------------------
※ConnectFlg(n)   …Boolean型のフラグ。

Private Sub tcpServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    
Dim i As Integer                       'ループカウンタ
'接続要求がきたとき
'相手アプリからの接続要求を受け付ける
If Index = 0 Then
    intConnectMax = intConnectMax + 1  '接続クライアント数を一台増やす
    For i = 0 To intConnectMax         '接続ループ
        If ConnectFlg(i) = False Then  'i番目のコントロールが非接続かどうか
                Exit For               '非接続の時、ループを脱出する
        End If
    Next
    Load tcpServer(i)                  'サーバコントロールのロード
    tcpServer(i).Accept requestID      'クライアントとの接続を受け入れる
    ConnectFlg(i) = True               '接続フラグを立てる
End If
    
End Sub
---------------------------------------------------------------------------------------------
※CloseイベントのときはIndex値で閉じたサーバコントロールと同じフラグを閉じるようにしました。
Private Sub tcpServer_Close(Index As Integer)
    
    '接続が切断された
    tcpServer(Index).Close                            '接続しているサーバを閉じる
    intConnectMax = intConnectMax - 1                 '接続クライアント数を1台分減らす。
    Unload tcpServer(Index)                           'サーバコントロールの開放
    ConnectFlg(Index) = False                         '接続フラグの設定
End Sub
---------------------------------------------------------------------------------------------
以上です。長文失礼しました。

それにフォレストさん、いろいろとご意見をいただきまして、ありがとうございました。 m(_ _)m