先看两个函数,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); // 读取数据流
的时候,程序就自动退出了,不能理解啊,求大神帮助!!!

解决方案 »

  1.   

    ehlo .... 后面要加CRLF
      

  2.   

    额,Writestring 没写出来,里面自动加了的: protected void WriteString(NetworkStream netStream, string str)
            {
                str = str + "/r/n"; // 加入换行符            // 将命令行转化为byte[]
                byte[] bWrite = Encoding.GetEncoding(helper.languageEncoding).GetBytes(str.ToCharArray());            // 由于每次写入的数据大小是有限制的,那么我们将每次写入的数据长度定在75个字节,一旦命令长度超过了75,就分步写入。
                int start = 0;
                int length = bWrite.Length;
                int page = 0;
                int size = 75;
                int count = size;
                try
                {
                    if (length > 75)
                    {
                        // 数据分页
                        if ((length / size) * size < length)
                            page = length / size + 1;
                        else
                            page = length / size;
                        for (int i = 0; i < page; i++)
                        {
                            start = i * size;
                            if (i == page - 1)
                                count = length - (i * size);
                            netStream.Write(bWrite, start, count); // 将数据写入到服务器上
                        }
                    }
                    else
                        netStream.Write(bWrite, 0, bWrite.Length);
                }
                catch (Exception)
                {
                    // 忽略错误
                }
            }
      

  3.   

    不要屏蔽exception 看看exception 是什么,和发送完返回的是什么?
      

  4.   


    刚试了下throw e 但是什么都没发生~ 前面说错了,程序倒是没有退出,单步跟踪到
    size = netStream.Read(by, 0, by.Length); // 读取数据流
    执行完后调试器自动中断了,内容是:调试器会话发生中断,因为某个用户暂停了该会话。点击调试最后一步就跳到了program.cs里的
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());  
            }最后一句左边有个绿色箭头,写着 :这是该线程从当前函数返回时要执行的下一条语句        
      

  5.   

    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错开了。