数码冲印数码照片网上冲印
站内搜索: 分类: 关键字:
您的位置:首页网站设计.Net专栏 → 使用C#进行SMTP协议客户端开发心得--读取服务器应答篇
使用C#进行SMTP协议客户端开发心得--读取服务器应答篇
日期:2005-10-30 22:30:02 人气:     [ ]
数码冲印 网上冲印

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



出处:世纪开元网上冲印搜集整理 作者:佚名
评论人 评论内容摘要(共 条,查看完整内容) 得分 发表时间
本类热点
01.关于vc的mshflexgrid控件的用法(转载:原地址:..
02.用实例学:ASP.NET的include的用法
03.ListView的使用
04.ASP.NET POST方式提交数据!
05.正态分布的随机数发生器 in C#
06.在.net安装程序中部署oracle客户端全攻略
07.蛙蛙推荐:C#编码规范.doc
08.在ASP.NET中处理datetime的一些通用函数(VB)
09.用户 NT AUTHORITY\NETWORK SERVICE 登录失败解决..
10.破译动网验证码的简单方法
本类推荐
网上数码冲印专用QQ:71086443  网上数码冲印专用MSN:photo36588@hotmail.com 网上冲印热线电话:0531-82678928
http://www.36588.com.cn 世纪开元数码照片网上冲印©2001 - 2008
网站地图 | 冲印知识 | 会员利益 | 服务价格 | 质量承诺 | 服务条款 | 隐私政策 | 商业合作 | 关于我们