C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: メール受信コマンドでフリーズ


(過去ログ 93 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■55614 / inTopicNo.1)  メール受信コマンドでフリーズ
  
□投稿者/ RHK (1回)-(2010/12/07(Tue) 15:45:28)

分類:[VB.NET/VB2005 以降] 

開発環境:Windows 2000 Professional SP4
実行環境:Windows Server 2003
いずれの環境も NETFrameWork2.0 あり
使用言語:VB2005

POP3コマンドを使用したメール受信PGを、ずっと終了させずに
あげっぱなしの状態で動かしていますが、
QUITコマンドを送信して、結果を受信する際にフリーズする現象が
発生しました。

ソースとしては、
Public Function Receive( _
ByVal hostName As String, _
ByVal portNumber As Integer, _
ByVal userId As String, _
ByVal passWord As String, _
ByVal deleteMails As Boolean) As String()
Dim mails() As String
Dim msg As String = ""
Dim stream As NetworkStream

'TcpClientの作成
Dim client As New TcpClient
'タイムアウトの設定
client.ReceiveTimeout = intReceiveTimeout
client.SendTimeout = intSendTimeout

Try
'サーバーに接続
client.Connect(hostName, portNumber)
'ストリームの取得
stream = client.GetStream()
'受信
msg = ReceiveData(stream)

'USERの送信
SendData(stream, "USER " + userId + vbCrLf)
'受信
msg = ReceiveData(stream)

'PASSの送信
SendData(stream, "PASS " + passWord + vbCrLf)
'受信
msg = ReceiveData(stream)

'STATの送信
SendData(stream, "STAT" + vbCrLf)
'受信
msg = ReceiveData(stream)
'メール数の取得
Dim mailsCount As Integer = _
Integer.Parse(msg.Split(" "c)(1))
If mailsCount <= 0 Then
'受信メールがない場合
mails = New String(0) {}
mails(0) = vbNullString
Else
'受信メール1件以上あり
mails = New String(mailsCount - 1) {}
End If

'すべてのメールの内容を受信
Dim i As Integer
For i = 1 To mailsCount
'RETRの送信(メールを受信)
SendData(stream, "RETR " + i.ToString() + vbCrLf)
'受信
msg = ReceiveData(stream, True)
mails((i - 1)) = msg.Substring((msg.IndexOf(vbCrLf) + 2))

'メールを削除するか
If deleteMails Then
'DELEの送信(メールに削除マークを付ける)
SendData(stream, "DELE " + i.ToString() + vbCrLf)
'受信
msg = ReceiveData(stream)
End If
Next i

'QUITの送信
SendData(stream, "QUIT" + vbCrLf)
'受信
msg = ReceiveData(stream)
Catch ex As Exception
S_UpdateListSet("メール受信エラー発生")
lw.LogAdd(LogWriter.lvFATAL, "メール受信エラーが発生しました")
Finally
'切断
client.Close()
End Try

Return mails
End Function

'データを受信する
Private Overloads Shared Function ReceiveData( _
ByVal stream As NetworkStream, _
ByVal multiLines As Boolean, _
ByVal bufferSize As Integer, _
ByVal enc As Encoding) As String
Dim data(bufferSize - 1) As Byte
Dim len As Integer
Dim msg As String = ""
Dim ms As New System.IO.MemoryStream

'すべて受信する
Do
'受信
len = stream.Read(data, 0, data.Length)
ms.Write(data, 0, len)
'文字列に変換する
msg = enc.GetString(ms.ToArray())
Loop While stream.DataAvailable OrElse _
((Not multiLines OrElse msg.StartsWith("-ERR")) AndAlso _
Not msg.EndsWith(vbCrLf)) OrElse _
(multiLines AndAlso Not msg.EndsWith(vbCrLf + "." + vbCrLf))

ms.Close()

'"-ERR"を受け取った時は例外をスロー
If msg.StartsWith("-ERR") Then
Throw New ApplicationException("Received Error")
End If

Return msg
End Function
Private Overloads Shared Function ReceiveData( _
ByVal stream As NetworkStream, _
ByVal multiLines As Boolean, _
ByVal bufferSize As Integer) As String
Return ReceiveData(stream, multiLines, bufferSize, _
Encoding.GetEncoding(50220))
End Function

Private Overloads Shared Function ReceiveData( _
ByVal stream As NetworkStream, _
ByVal multiLines As Boolean) As String
Return ReceiveData(stream, multiLines, 256)
End Function

Private Overloads Shared Function ReceiveData( _
ByVal stream As NetworkStream) As String
Return ReceiveData(stream, False)
End Function


この原因の推測としては、QUITコマンドの結果を受信する際
(上記 ReceiveData 関数を呼び出しています)、
・ 受信結果の終端文字が CRLF でない状態が続く。
・ コマンドを送信しても、結果を全く返していない。
が考えられます。

・ 1つのPOP3コマンドの受信結果の終端文字は、CRLF であるが、
受信結果の終端文字が CRLF でないケースはありうるでしょうか?
・ POP3コマンドを送信しても、永久的に結果応答を返さないケースは
ありうるでしょうか?

ちなみに、15秒間隔でメール受信しています(上記 Receive 関数を呼び出しています)。

引用返信 編集キー/
■55627 / inTopicNo.2)  Re[1]: メール受信コマンドでフリーズ
□投稿者/ shu (254回)-(2010/12/07(Tue) 21:32:31)
No55614 (RHK さん) に返信

ステップ実行してどんなデータが入っているか確認してみはどうでしょう?
引用返信 編集キー/
■55629 / inTopicNo.3)  Re[1]: メール受信コマンドでフリーズ
□投稿者/ .SHO (1376回)-(2010/12/07(Tue) 22:42:17)
No55614 (RHK さん) に返信

> ・ POP3コマンドを送信しても、永久的に結果応答を返さないケースは
> ありうるでしょうか?

ありうるかどうかで言うなら、ありうるでしょうね。
POP3コマンドを送信した直後にサーバがぶっ壊れるとか・・・

引用返信 編集キー/
■55653 / inTopicNo.4)  Re[2]: メール受信コマンドでフリーズ
□投稿者/ PATIO (72回)-(2010/12/08(Wed) 13:37:58)
No55629 (.SHO さん) に返信
> ■No55614 (RHK さん) に返信
>
>>・ POP3コマンドを送信しても、永久的に結果応答を返さないケースは
>> ありうるでしょうか?
>
> ありうるかどうかで言うなら、ありうるでしょうね。
> POP3コマンドを送信した直後にサーバがぶっ壊れるとか・・・

でもって、そういう場合にも対応できるようにプログラムを組むのか、
それはレアケースだから強制終了でいいやとするのかは、
プログラムの仕様としてどう対処するかの話ですね。
ユーザーに対して優しいのは勿論前者ですけれど。

起こりうる事象全てに対応するのは難しいですが、
出来る限り対処できた方が良いのは言わずもがなですね。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -