smtp 应答

 

以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位应答码开始,加一个空格,然后是一些发回的数据流,结尾是回车加换行的正确命令格式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值