程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 使用C#進行SMTP協議客戶端開發心得--讀取服務器應答篇

使用C#進行SMTP協議客戶端開發心得--讀取服務器應答篇

編輯:.NET實例教程

以TcpClIEnt連接方式為例,首先取得服務器發回的數據流。

NetworkStream streaMaccount=tcpClIEnt.GetStream();

當我們對smtp服務器發送請求,例如連接,傳送用戶名,密碼後,服務器會返回應答數據流。

我們必須對服務器返回數據流進行讀取,這一步我經歷了3次改動。

最開始的程序是按照《Visaul C#.Net網絡核心編程》這本書上的例子來寫的:

private string ReadFromNetStream(ref NetworkStream NetStream)
{
byte[] by=new byte[512];
NetStream.Read(by,0,by.Length);
string read=System.Text.Encoding.ASCII.GetString(by);
return read;
}

這種方式其實就是把讀到的數據流全部變成字符串形式,但是實際網絡傳輸中,smtp服務器發回的其實不一定全部是有效的命令,命令都是以<CRLF>(回車加換行)結束的。因此這樣的讀取方式存在問題。

修改以後的代碼如下:

private string ReadFromNetStream(ref NetworkStream NetStream,string strEndFlag)
{
string ResultData = "";
byte[] ubBuff=new byte[1024];
try
{
while(true)
{
int nCount = NetStream.Read(ubBuff,0,ubBuff.Length);
if( nCount > 0 )
{
ResultData += Encoding.ASCII.GetString( ubBuff, 0, nCount);
}

if( ResultData.EndsWith(strEndFlag) )
{
break;
}

if( nCount == 0 )
{
throw new System.Exception("timeout");
}
}
}
catch(System.Exception se)
{
throw se;
MessageBox.Show(se.ToString());
return "";
}
return ResultData;
}

這樣一來,就可以截取出以回車換行結束的命令。但是這樣做還是不夠正確的,因為smtp服務器在某些情況下會發回一些歡迎信息之類的東西,它們也是以<CRLF>(回車加換行)結束的,我們用上邊的程序得到的很有可能不是我們實際想要得到的正確命令。

於是我只有再次修改程序如下:

/**
*
* 讀取服務器的返回信息流
*
*/
public string ReadFromNetStream(ref NetworkStream NetStream)
{

if( NetStream == null )
return "";

String ResultData = "";
try
{
while(true)
{
string LineData = ReadLineStr(NetStream);
if( null != LineData
&& LineData.Length > 4)
{
if(LineData.Substring(3,1).CompareTo(" ") != 0)
{
ResultData += LineData + "\r\n";
continue;
}


else
{
ResultData += LineData;
break;
}
}
else
{
ResultData += LineData;
break;
}
}
}
catch(Exception e)
{
throw e;
}

return ResultData;
}

/**
*
* 逐行讀取服務器的返回信息
*
*/
public byte[] readLine(NetworkStream m_StrmSource)
{
ArrayList lineBuf = new ArrayList();
byte prevByte = 0;

int currByteInt = m_StrmSource.ReadByte();
while(currByteInt > -1)
{
lineBuf.Add((byte)currByteInt);

if((prevByte == (byte)'\r' && (byte)currByteInt == (byte)'\n'))
{
byte[] retVal = new byte[lineBuf.Count-2];
lineBuf.CopyTo(0,retVal,0,lineBuf.Count-2);

return retVal;
}

prevByte = (byte)currByteInt;

currByteInt = m_StrmSource.ReadByte();
}


if(lineBuf.Count > 0)
{
byte[] retVal = new byte[lineBuf.Count];
lineBuf.CopyTo(0,retVal,0,lineBuf.Count);

return retVal;
}

return null;
}

/**
*
* 將服務器的返回信息逐行轉換成字符串
*
*/
public string ReadLineStr(NetworkStream myStream)
{
byte[] b = readLine(myStream);
if( null == b)
{
return null;
}
else
{
return System.Text.Encoding.ASCII.GetString( b );
}
}

這樣一來,我們就能讀到那些以3位應答碼開始,加一個空格,然後是一些發回的數據流,結尾是回車加換行的正確命令格式。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved