日期:2014-05-18  浏览次数:20809 次

TCP发送SMTP邮件中,连接成功但输入EHLO了后就接不到服务器的回复指令了,求解啊!!!
先看两个函数,

Command函数为:

  protected bool Command(NetworkStream netStream, string command, string state)
  {
  string sp = null;
  bool success = false;
  try
  {
  WriteString(netStream, command); // 写入命令
  sp = ReadString(netStream); // 接受返回信息
  if (sp.IndexOf(state) != -1) // 判断状态码是否正确
  success = true;
  }
  catch (Exception)
  {
  // 忽略错误
  }
  return success;
  }

里面的Writestring 就不用管了,没问题,关键是 Readstring,如下:
   


  protected string ReadString(NetworkStream netStream)
  {
  string sp = null;
  byte[] by = new byte[1024];
  int size=0;
  try
  {
  size = netStream.Read(by, 0, by.Length); // 读取数据流
  }
  catch (Exception)
  {

  }
   
  if (size > 0)
  {
  sp = Encoding.Default.GetString(by); // 转化为String
  }
  return sp;
  }


下面是主程序里的,


  TcpClient tcpClient = null;
  try
  {
  tcpClient = new TcpClient(helper.server, 25);
  }
  catch (Exception)
  {
  throw new Exception("无法连接服务器");
  }

  ReadString(tcpClient.GetStream());
  if (!Command(tcpClient.GetStream(), "EHLO Localhost", "250"))
  throw new Exception("登陆阶段失败");



好了,一到if (!Command(tcpClient.GetStream(), "EHLO Localhost", "250"))里的Readstring执行到
size = netStream.Read(by, 0, by.Length); // 读取数据流
的时候,程序就自动退出了,不能理解啊,求大神帮助!!!

------解决方案--------------------
ehlo .... 后面要加CRLF

------解决方案--------------------
TCP发送mail其实就是模拟telnet发送mail。
那么最重要的时候,你需要知道服务器的send和recv时机。
我之前写这个程序的时候,出现过一个问题:
我单步调试完全没有错误,但是我一旦run起来,错误就出来了。

原因就出现在,我不清楚smtp服务器的发送逻辑。
后来通过log我发现了问题,我用流程写一下:
客户端-》连接
服务端-》hello
服务端-》welcome
客户端-》登陆信息
服务端-》登陆完毕
客户端-》发送邮件

流程是这样的,你自己看看服务端的发送逻辑,发现什么了没?服务端在我的客户端连接之后连续分两次send,然后才recv。我在单步调试过程中,因为单步调试话费的时间比程序运行要慢很多很多,所以我单步调试的时候,服务端的两次send都来得及发送了,所以我一直以为服务端的hello和welcome是一次send,所以我在连接之后,recv一次,马上就开始send登陆信息。这样就造成了,我还是用流程画一下:
客户端-》连接
服务端-》hello
客户端-》登陆信息
服务端-》welcome
服务端recv等待登陆信息,发现了问题了没?我的客户端的登陆信息是在服务端的recv之前就发送了,所以服务端以为我的客户端没有发送,就一直等,等到超时之后,就关闭了连接,出现了你之前说的错误。

建议:
将整个流程使用log记录下来,你就能看出来到底是不是recv和send错开了。