- PR -

ソケット通信での接続確認

1
投稿者投稿内容
yamayama
ベテラン
会議室デビュー日: 2006/02/10
投稿数: 68
投稿日時: 2007-07-19 01:13
いつもお世話になります。

VB 2005のサーバプログラムにおいて、同期制御にて処理を行っているのですが、
@リスナーの開始
AAccept
Bデータの受信処理
C業務ロジック
DBに戻る。
といった具合に処理したいと考えています。
この際、クライアント側の接続状態が切れているかどうかの判断を
BにおいてNetworkStreamのReadメソッドが0バイトを返した場合、
切断と判断できると考えていたのですが、
実際にはクライアント側の端末のケーブルを外しても接続切れを検知することは
できませんでした。
どうにかして、接続が切れているかどうかの判断をすることはできないでしょうか?
又、
代替策として、同じポートに対し、クライアントが接続してきた場合、
受信をやめ、Acceptから開始できないかと考えているのですが、
何かよい方法などありませんでしょうか?
説明が長くなり申し訳ありませんが、よろしくお願いします。
下記にコーディングを記載します。

Dim listener As New System.Net.Sockets.TcpListener(IP, port)
listener.Start() '@リスニング開始
'A接続要求があったら受け入れる
Dim tcp As System.Net.Sockets.TcpClient = listener.AcceptTcpClient()
 Dim myNetWork As System.Net.Sockets.NetworkStream = tcp.GetStream()
・・・
Do
'Bデータ受信
Dim resBytes(tcp.ReceiveBufferSize) As Byte
resSize = myNetWork.Read(resBytes, 0, resBytes.Length)

'Readが0を返した時はクライアントが切断したと判断
If resSize = 0 Then
Exit do
End If
'C業務ロジック
 ・・・
Loop While myNetWork.DataAvailable
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2007-07-19 09:36
諸農です。

引用:

代替策として、同じポートに対し、クライアントが接続してきた場合、
受信をやめ、Acceptから開始できないかと考えているのですが、
何かよい方法などありませんでしょうか?



ちょっとよく判らないのですが、接続待ちから接続→受信処理って別スレッドにしているとかではなく、1つのクライアントが接続するとその後の接続待ち処理はブロックされてしまって他のクライアントは接続できないことになっているのですか?

プロトコルを変更する必要があるかも知れませんが、接続時に認証かなんかでクライアントを管理しておいて同じ認証で接続してきたら前のサーバー側のクライアントをCloseして破棄すればいいんじゃないでしょうか。現実解かどうかはちょっと判りませんが。

@ITの過去の記事にTcpListenerを使った簡単なファイル転送アプリの実装解説があったと思います。切断検知云々の話はなかったと思いますが、参考にはなるのではないでしょうか。

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-07-19 10:00
引用:

yamayamaさんの書き込み (2007-07-19 01:13) より:
実際にはクライアント側の端末のケーブルを外しても接続切れを検知することは
できませんでした。


TCPでは非正規の手順で切断された場合に、それを検出するための機能を提供していません。したがってケーブルをはずした場合に、それを検出できないのは当然です。

引用:

どうにかして、接続が切れているかどうかの判断をすることはできないでしょうか?


何らかのデータを送信してください。通信経路に問題があり、相手先まで到達できないのであればエラーになります。このエラーをもって切断を検知できるでしょう。切断検知が必要な場合には、プロトコルとして定周期でのデータ送信などを行うのが一般的です。

KeepAliveを有効にすると、TCPプロトコルスタックがバックグラウンドでデータの送受信を定期的に行い、通信経路の異常を検知できます。ですが、デフォルトだと2時間周期と周期が長いので、あまり使えないかと・・・。

引用:

受信をやめ、Acceptから開始できないかと考えているのですが、
何かよい方法などありませんでしょうか?


普通はAcceptと、データの送受信はまったく別のスレッドで行います。そうしないと複数の接続を捌けませんから。
yamayama
ベテラン
会議室デビュー日: 2006/02/10
投稿数: 68
投稿日時: 2007-07-20 07:51
ご回答いただきありがとうございます。

【普通はAcceptと、データの送受信はまったく別のスレッドで行います。そうしないと複数の接続を捌けません】

との事で
Acceptを非同期処理に変えて、現在のポートにクライアントからの接続があった場合、前回の接続のスレッドを閉じ、新規のスレッドにて処理するような事ができれば、対応できるようなのですが、
実装方法としての良いサンプルなどありませんでしょうか?
宜しくお願いします。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2007-07-20 11:18
諸農です。

引用:

Acceptを非同期処理に変えて、現在のポートにクライアントからの接続があった場合、前回の接続のスレッドを閉じ、新規のスレッドにて処理するような事ができれば、対応できるようなのですが、
実装方法としての良いサンプルなどありませんでしょうか?



前にも書きましたが、@ITの過去の記事では役に立ちませんでしたか?
それとも探していない?

.NETネットワーク・プログラミング入門


_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
1

スキルアップ/キャリアアップ(JOB@IT)