自己用c#写的一个用TcpClient和NetworkStream来发送邮件的程序,附件在8k左右没有问题,附件在80k或更多的时候就会发送不出去,设置发送缓冲区为1000000时 提示错误“服务未就绪,关闭传输信道”
不设置发送缓冲区,就是默认的发送缓冲区时错误提示如下:
System.IO.IOException: 无法将数据写入传输连接。 ---> System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接。
at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
 at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
  at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
  at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
 at System.IO.StreamWriter.Flush()
  at ReadTheSameFile.SmtpEmail.SendCommand(String str) in d:\\mytest\\readthesamefile\\smtpemail.cs:line 431这是怎么回事!怎么解决?

解决方案 »

  1.   

    把附件压缩一下好了,sharpziplib or gzipstream
      

  2.   

    要是挝发送的文件压缩后还有2M怎么办 ,为什么foxmail就能给163发送好几M的附件,我的怎么就不行,问题出在那里?
      

  3.   

    用TcpClient和NetworkStream来发送邮件?没有用过。思路太复杂了吧。
      

  4.   

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net.Mail;
    using System.Net;namespace IMSEmailService
    {
        public class EmailHelper
        {
            private string _title;
            private string _content;
            private string _toEmail;        public string Title
            {
                get { return _title; }
                set { _title = value; }
            }
            public string Content
            {
                get { return _content; }
                set { _content = value; }
            }
            public string ToEmail
            {
                get { return _toEmail; }
                set { _toEmail = value; }
            }        public void Send()
            {
                Setting config = new Setting();            MailMessage mail = new MailMessage();
                mail.Subject = _title;
                mail.Body = _content;
                mail.To.Add(_toEmail);            
                mail.IsBodyHtml = config.IsBodyHtml.ToLower()=="true";
                mail.From = new MailAddress(config.MailFrom);
                SmtpClient smtp = new SmtpClient(config.SmtpServer, config.Port);
                if (config.Authentication.ToLower() == "true")
                {
                    NetworkCredential myCredentials = new NetworkCredential(config.Account, config.PassWord, "");
                    smtp.Credentials = myCredentials;
                }
                if (config.UseSSL.ToLower()=="true")
                {
                    smtp.EnableSsl = true;            }
                try
                {
                    smtp.Send(mail);
                }
                catch (System.Net.Mail.SmtpException ex)
                {
                    Console.Write(ex.Message);
                }
                Console.Write("Send OK!");
            }
        }}
      

  5.   

    添加附加的方法:
    mail.Attachments.Add(new Attachment("c:\\1.txt"));
      

  6.   

    我的没有用MailMessage 类 smtp命令的发送也是自己写的 附件大了就出错 郁闷
      

  7.   

    发送附件程序是这样的
    if(Attachments.Count!=0) 

    foreach(string filepath in Attachments) 
    {  SendBufferstr += "------=_NextPart_000_00D6_01C29593.AAB31770"+enter; 
    SendBufferstr += "Content-Type: application/octet-stream"+enter; 
    SendBufferstr += "   name=\"=?"+Charset.ToUpper()+"?B?"+Base64Encode(filepath.Substring(filepath.LastIndexOf("\\")+1))+"?=\""+enter; 
    SendBufferstr += "Content-Transfer-Encoding: base64"+enter; 
    SendBufferstr += "Content-Disposition: attachment;"+enter; 
    SendBufferstr += "   filename=\"=?"+Charset.ToUpper()+"?B?"+Base64Encode(filepath.Substring(filepath.LastIndexOf("\\")+1))+"?=\""+enter+enter; 
    SendCommand(SendBufferstr);
    SendBufferstr = GetStream(filepath)+enter+enter;
    if(SendBufferstr.Length<=1024)
    {
    SendCommand(SendBufferstr);
    }
    else
    {
    while(SendBufferstr.Length>1024)
    {
    string tpstr = SendBufferstr.Substring(0,1024);
    SendBufferstr = SendBufferstr.Substring(1024);
    SendCommand(tpstr);
    if(SendBufferstr.Length<=1024)
    {
    SendCommand(SendBufferstr);
    break;
    }
    }
    }


    else
    {
    SendBufferstr += enter;
    }
    SendBufferstr = "------=_NextPart_000_00D6_01C29593.AAB31770--"+enter+enter; 
    SendBufferstr += enter + "." + enter; 发送的方法是
    private bool SendCommand(string str) 

    if(str==null||str.Trim()=="") 

    return true; 

    try 

    _StreamWriter.Write(str);
    _StreamWriter.Flush();

    catch(System.Exception ex) 

    errmsg=ex.ToString(); 
    return false; 

    return true; 
    }这样不知道是不是多次发送数据到缓冲区
    希望高人指教
      

  8.   

    GetStream(filepath)得到的是字符串?
    _StreamWriter怎么来的. 写到哪儿?
      

  9.   

    对 GetStream(filepath) 得到的是Base64编码后的字符串,
    _StreamWriter 实在开始发送的时候生命的
    //连接网络 
    try 

    tc=new TcpClient(mailserver,mailserverport); 

    catch(Exception e) 

    errmsg=e.ToString(); 
    return false; 
    }  ns = tc.GetStream(); 
    //
    _StreamReader = new StreamReader(ns, 
    System.Text.Encoding.Default, false, tc.ReceiveBufferSize);
    _StreamWriter = new StreamWriter(ns, 
    System.Text.Encoding.Default, tc.SendBufferSize);
      

  10.   

    设置ns.ReadTimeout和ns.WriteTimeout为Timeout.Infinite试试.
    你的程序是在
    SendBufferstr = GetStream(filepath)+enter+enter;这一步出问题吗,
    还是后面写的时候.
      

  11.   

    我这没有发现ns.ReadTimeout和ns.WriteTimeout 这两个属性呀
    SendBufferstr = GetStream(filepath)+enter+enter;这一步没问题
    就是党附件大的时候,80K就不行了 出错误
      

  12.   

    我找了个c++的发送邮件的例子 他发送10几兆的附件都没问题 她的附件发送代码如下:我看和C#写的没什么 区别亚 我的怎么就不行呢
    //以下进行附件的处理:
    if(m_szFilenames.GetSize() != 0)
    {
    szTemp = "--www.LuoCong.com\r\n";
    szTemp += "Content-Type:application/octet-stream;Name=%s\r\n";
    szTemp += "Content-Disposition:attachment;FileName=%s\r\n";
    szTemp += "Content-Transfer-Encoding:Base64\r\n\r\n";
    szTemp += "%s\r\n\r\n"; szContent = szFrom + szTo + szDateTime + szSubject + szBodyHead + szBody;
    for(int i = 0; i < m_szFilenames.GetSize(); i++)
    {
    CFile hFile;
    if(hFile.Open(m_szFilenames.GetAt(i), CFile::modeRead))
    {
    DWORD dwFileSize = hFile.GetLength();
    CString szFileBuffer;
    hFile.Read(szFileBuffer.GetBuffer(dwFileSize), dwFileSize);
    szAttachment.Format(szTemp, hFile.GetFileName(), hFile.GetFileName(), Base64.Encode(szFileBuffer, dwFileSize));
    szFileBuffer.ReleaseBuffer();
    hFile.Close();
    szContent += szAttachment;
    }
    } //连接成 Content :
    szContent += "--www.LuoCong.com--\r\n.\r\n";
    }
    else
    {
    //连接成 Content :
    szContent = szFrom + szTo + szDateTime + szSubject + szBodyHead + szBody + "--www.LuoCong.com" + "\r\n.\r\n";
    } //发送 Content :
    m_wsSMTPServer.Send((LPCTSTR)szContent, szContent.GetLength());
    我对C++不是太懂
      

  13.   

    ns.ReadTimeout和ns.WriteTimeout 这两个属性2.0是才有的.对C++一窍不通, 看你贴上来的程序好像是一次把所有内容发送了. 没有循环发送.
      

  14.   

    小小意见:
    1. 你所写的代码和那个c++版本的不太一样。第一,Content-Disposition:attachment 和 Content-Transfer-Encoding:Base64 顺序不一样;第二,c++是把附件内容转为字符串加到Content-Transfer-Encoding:Base64\r\n\r\n后的,你的GetStream()不知道是路径还是内容。
    2. 不要使用StreamWriter,直接使用TcpClient.Send()发送。
      

  15.   

    web.config里面加上一句
    <httpRuntime executionTimeout="300" maxRequestLength="102400"/>
    可以发送几m的附件
    再大了去网上搜索吧
      

  16.   

    用c#写的smtp程序利用公司的邮箱登陆发送十几兆的附件都没问题,利用163的用户登陆超多几十K就报错。但是一个用c++写的发送邮件的程序利用163的用户登陆就能发送好几兆的附件。很是纳闷