DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ソケット通信について

分類:[.NET]

以前同じような質問をしたのですが、現在ソケット通信のサーバーを作成しているのですがクライアント側が切断した時、サーバー側でも切断したいと質問し、解答を頂き作成しましたが、また問題が発生してしましました。
 以下の様に作成しているのですが、クライアント側で切断された時に切断することはできるようになったのですが、クライアント側が接続しただけで何もデータを送信してこなかったり、切断も行わない場合、Readメソッドでブロックされていまい、アプリケーションを終了することもできないのです。何か方法はないのでしょうか?
-------------------------------------------------------------------------
Private myListener As System.Net.Sockets.TcpListener
Private myTcpClient As System.Net.Sockets.TcpClient

'// リスナー開始 //
myListener.Start()

myTcpClient = myListener.AcceptTcpClient

Try
If myTcpClient.GetStream.CanRead Then
Do
mintRecvBufSize = myTcpClient.GetStream.Read _
(mabytRdData, 0, mabytRdData.Length)
'// 受信データなし -> クライアント切断 //
If mintRecvBufSize = 0 Then
'// クライアントが接続切断
Exit Do
ElseIfIf mintRecvBufSize > 0 Then
'// データ受信
Exit Do
End If
Loop
End If
Catch Ex as Exception

End Try
■No1208に返信(イルカさんの記事)
自分もあまり詳しくないから深くはわからないですが

> mintRecvBufSize = myTcpClient.GetStream.Read _
> (mabytRdData, 0, mabytRdData.Length)

上記のReadメソッドを行う前に、DataAvailableプロパティをみてデータが受信できるか確認をすればいいかと思います。
If myTcpClient.GetStream.DataAvailable Then
mintRecvBufSize = myTcpClient.GetStream.Read _
(mabytRdData, 0, mabytRdData.Length)
End If
↑こんな感じ


> ElseIfIf mintRecvBufSize > 0 Then
> '// データ受信
> Exit Do
> End If
ちなみにサンプルで読み取ったバイト数が0を超えてたら//データ受信とありますが、Readメソッドを実行したときに引数で渡しているmybytRdDataに格納されます。
■No1256に返信(MSTさんの記事)
> ■No1208に返信(イルカさんの記事)
> 上記のReadメソッドを行う前に、DataAvailableプロパティをみてデータが受信できるか確認をすればいいかと思います。
> If myTcpClient.GetStream.DataAvailable Then
> mintRecvBufSize = myTcpClient.GetStream.Read _
> (mabytRdData, 0, mabytRdData.Length)
> End If
> ↑こんな感じ
>
>
>> ElseIfIf mintRecvBufSize > 0 Then
>> '// データ受信
>> Exit Do
>> End If
ありがとうございます
でもDataAvailableプロパティをみるとクライアント側から切断された時が分からないのですが…
DataAvailableプロパティを使用すると受信した後、Falseになり切断されたと認識しているReadメソッドに0バイトデータが受信というのが確認できないのですが
■No1302に返信(イルカさんの記事)
現在.NETが使えなくてテストをする事ができないのですが、
MSDNをみると下記のように解説してありました。

Read メソッドは、リモート ホストからデータを受信し、そのデータが読み取り用のネットワーク バッファ内のキューに置かれるまで実行をブロックします。ブロックしない場合は、 DataAvailable メソッドを使用してこのデータが使用可能かどうかを確認します。 DataAvailable が true の場合、 Read メソッドの実行はすぐに終了します。リモート ホストがシャットダウンするか接続を閉じると、 DataAvailable は SocketException をスローします。

これを参考に考えなおしてみると

Dim boolDA as Boolean
Do
Try
boolDA = myTcpClient.GetStream.DataAvailable
Catch Ex as Exception
Msgbox("接続が切断されました。")
Exit Do
End Try
If boolDA Then
mintRecvBufSize = myTcpClient.GetStream.Read _
(mabytRdData, 0, mabytRdData.Length)
//終了条件を判定して終了処理(1回の受信で終了や"Exit"を受信したらEnd等)
End If
Loop

こんな感じでできないでしょうか。
■No1309に返信(MSTさんの記事)
すいません
>Catch Ex as Exception
の部分は「Catch Ex as SocketException」 ですね
■No1309に返信(MSTさんの記事)
> ■No1302に返信(イルカさんの記事)
> Read メソッドは、リモート ホストからデータを受信し、そのデータが読み取り用のネットワーク バッファ内のキューに置かれるまで実行をブロックします。ブロックしない場合は、 DataAvailable メソッドを使用してこのデータが使用可能かどうかを確認します。 DataAvailable が true の場合、 Read メソッドの実行はすぐに終了します。リモート ホストがシャットダウンするか接続を閉じると、 DataAvailable は SocketException をスローします。
>
> これを参考に考えなおしてみると
>
> Dim boolDA as Boolean
> Do
> Try
> boolDA = myTcpClient.GetStream.DataAvailable
> Catch Ex as Exception
> Msgbox("接続が切断されました。")
> Exit Do
> End Try
> If boolDA Then
> mintRecvBufSize = myTcpClient.GetStream.Read _
> (mabytRdData, 0, mabytRdData.Length)
> //終了条件を判定して終了処理(1回の受信で終了や"Exit"を受信したらEnd等)
> End If
> Loop
>
> こんな感じでできないでしょうか。
それも試してみたのですがクライアントが切断された時SocketExceptionの例外は発生しないのですが…
■No1311に返信(イルカさんの記事)
すいません、.NETで試すこともできないので、これ以上はわかりません。
また何かわかったら報告します。
■No1338に返信(MSTさんの記事)
> ■No1311に返信(イルカさんの記事)
> すいません、.NETで試すこともできないので、これ以上はわかりません。
> また何かわかったら報告します。
考えてくださってありがとうございます。
自分もいろいろと調べてみます。

DOBON.NET | プログラミング道 | プログラミング掲示板