是不是sina的smtp服务器改变了认证方法,我以前写的邮件发送程序不管用了

解决方案 »

  1.   

    为什么连 CPJNSMTPConnection v2.42 也不行啊?
      

  2.   

    这是一个esmtp下可以发送多个附件的例子,最初是在freebsd下写的,我修改了下,现在可以在windows下面运行,原来它和smtp有很大的区别,严格区分换行<CR><LF>,也就是chr(13)和chr(10),smtp可以用\n直接代替<CR><LF>,esmtp却不允许
    功能不是很完善,有待改进//编译环境:BCC 5.5
    //原代码如下:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <windows.h>
    #include <winsock.h>
    #include <sys/stat.h>#pragma comment (lib, "ws2_32.lib")class SOCKETAPI{
    public:
    int InitServer(char *IP, int Port);
    int InitClient(char *IP, int Port);
    int SocketAccept(SOCKET);
    int SocketSend(SOCKET, char *, int);
    int SocketRecv(SOCKET, char *, int);
    void ErrorNote(char *, int);
    void TerminateSocket(SOCKET);
    private:
    int InitWSA();
    };int SOCKETAPI::InitWSA(){
    WSADATA w;
    if (WSAStartup(MAKEWORD(2,2), &w)!=0){
    ErrorNote("WSAStartup", WSAGetLastError());
    return 0;
    }
    return 1;
    }int SOCKETAPI::InitServer(char *IP_Addr, int Port){
    struct sockaddr_in server;
    SOCKET ServerSocket;
    if (!InitWSA())
    return 0;
    ServerSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (ServerSocket==INVALID_SOCKET){
    ErrorNote("socket", WSAGetLastError());
    return 0;
    }
    memset(&server, 0x0, sizeof(sockaddr_in));
    server.sin_family = AF_INET;
    server.sin_port = htons(Port);
    if (IP_Addr[0]==0x0){
    server.sin_addr.s_addr = INADDR_ANY;
    }else{
    server.sin_addr.S_un.S_addr = inet_addr(IP_Addr);
    }
    if (bind(ServerSocket, (struct sockaddr *)&server, sizeof(struct sockaddr))==SOCKET_ERROR){
    ErrorNote("bind", WSAGetLastError());
    return 0;
    }
    if (listen(ServerSocket, 2)){
    ErrorNote("listen", WSAGetLastError());
    return 0;
    }
    return ServerSocket;
    }int SOCKETAPI::SocketSend(SOCKET CSocket, char *buf, int len){
    int status = send(CSocket, buf, len, 0);
    if (status==SOCKET_ERROR){
    ErrorNote("send", WSAGetLastError());
    }
    return status;
    }int SOCKETAPI::SocketRecv(SOCKET CSocket, char *buf, int len){
    int status = recv(CSocket, buf, len, 0);
    if (status==SOCKET_ERROR){
    ErrorNote("recv", WSAGetLastError());
    }
    return status;
    }void SOCKETAPI::ErrorNote(char *event, int Error_ID){
    char filePath[255];
    time_t timer = time(NULL);
    struct tm *now = localtime(&timer);
    sprintf(filePath, "err\\SOCKET_%04d-%02d-%02d.txt", now->tm_year+1900, now->tm_mon+1, now->tm_mday);
    FILE *cfPtr = fopen(filePath, "a");
    if (cfPtr==NULL){
    system("md err");
    cfPtr = fopen(filePath, "a");
    }
    if (cfPtr!=NULL){
    printf("%-10s%-10d%02d:%02d:%02d\n", event, Error_ID, now->tm_hour, now->tm_min, now->tm_sec);
    fprintf(cfPtr, "%s,%d,%02d:%02d:%02d\n", event, Error_ID, now->tm_hour, now->tm_min, now->tm_sec);
    fclose(cfPtr);
    }
    }int SOCKETAPI::SocketAccept(SOCKET ServerSocket){
    struct sockaddr_in visite;
    int l = sizeof(visite);
    SOCKET CSocket;
    if (ServerSocket==INVALID_SOCKET)
    return 0;
    CSocket = accept(ServerSocket, (struct sockaddr *)&visite, &l);
    if (CSocket==INVALID_SOCKET){
    ErrorNote("accept", WSAGetLastError());
    return 0;
    }
    return CSocket;
    }int SOCKETAPI::InitClient(char *IP_Addr, int Port){
    struct sockaddr_in client;
    SOCKET CSocket;
    int o = 1;
    int t = 10000;
    if (!InitWSA())
    return 0;
    CSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (CSocket==INVALID_SOCKET){
    ErrorNote("socket", WSAGetLastError());
    return 0;
    }
    client.sin_family = AF_INET;
    client.sin_port = htons(Port);
    client.sin_addr.S_un.S_addr = inet_addr(IP_Addr);
    if (connect(CSocket, (struct sockaddr *)&client, sizeof(struct sockaddr))==SOCKET_ERROR){
    ErrorNote("connect", WSAGetLastError());
    return 0;
    }
    if (setsockopt(CSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&o, sizeof(o))==SOCKET_ERROR){
    ErrorNote("setsockopt", WSAGetLastError());
    return 0;
    }
    if (setsockopt(CSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&t, sizeof(t))){
    ErrorNote("setsockopt:SO_SNDTIMEO", WSAGetLastError());
    return 0;
    }
    if (setsockopt(CSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&t, sizeof(t))){
    ErrorNote("setsockopt:SO_RCVTIMEO", WSAGetLastError());
    return 0;
    }
    return CSocket;
    }void SOCKETAPI::TerminateSocket(SOCKET CSocket){
    if (CSocket!=INVALID_SOCKET)
    closesocket(CSocket);
    }char *GetIPAddress(char *sIn, char *sOut){
    struct hostent *HostIP;
    WSADATA wsad;
    int status;
    status=WSAStartup(MAKEWORD(2,2),&wsad);
    if (status==0){
    HostIP = gethostbyname(sIn);
    if(HostIP!=NULL){
      strcpy(sOut, inet_ntoa(*(LPIN_ADDR)*(HostIP->h_addr_list)));
      }
      WSACleanup();
     }
     return sOut;
    }typedef struct _XMAIL_NODE_{
    char smtp_addr[255];//smtp地址
    int smtp_port;//smtp端口
    char user_name[32];//用户名
    char user_pwd[32];//密码
    char fromaddr[255];//发送地址
    char toaddr[255];//接收地址
    char s_fromaddr[255];//邮件显示的发送地址
    char s_toaddr[255];//邮件显示的接收地址
    char subject[255];//主题
    char *text;//文本内容
    char *html;//html内容
    char attach[1024];//附件char * + 0x0 + char *+ 0x0 ....格式
    }XMAIL_NODE, *XMAIL_NODEPTR;#define MSGMAXLENGTH 1024//生成二进制头
    char *Binary(char *sOut){
    char *source = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
    int i,k,sl=strlen(source);
    *sOut = 0;
    strcat(sOut, "----=_NextPart_");
    srand(time(0));
    for (i=0;i<24;i++){
    k = rand()%sl+1;
    strncat(sOut, source+k, 1);
    }
    return sOut;
    }//base64加密
    void Base64Encode(char *sIn, int sl, char *sOut){
    char *source = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    int i;
    unsigned long t; t = 0;
    *sOut = 0;
    for (i=0;i<sl;i++){
    t <<= 8;
    t += *(sIn+i);
    if (i%3==2){
    *sOut++ = source[(t>>18) & 0x3f];
    *sOut++ = source[(t>>12) & 0x3f];
    *sOut++ = source[(t>>6) & 0x3f];
    *sOut++ = source[t & 0x3f];
    t = 0;
    }
    } switch(sl%3){
    case 1:
    t <<= 8;
    t <<= 8;
    *sOut++ = source[(t>>18) & 0x3f];
    *sOut++ = source[(t>>12) & 0x3f];
    *sOut++ = '=';
    *sOut++ = '=';
    break;
    case 2:
    t <<= 8;
    *sOut++ = source[(t>>18) & 0x3f];
    *sOut++ = source[(t>>12) & 0x3f];
    *sOut++ = source[(t>>6) & 0x3f];
    *sOut++ = '=';
    break;
    default:
    break;
    }
    *sOut = 0;
    }
      

  3.   

    //发送文件
    void x_sendfile(char *sIn, int csocket, char *bin){
    FILE *cfPtr;
    int fl;
    char *buf, *tmp, *p = sIn;
    struct stat s;
    while(strlen(p)>0){
    cfPtr = fopen(p, "r");
    if (cfPtr!=NULL){
    fstat(fileno(cfPtr), &s);
    fl = s.st_size;
    buf = (char *)malloc(fl*2);
    fread(buf, fl, 1, cfPtr);
    fclose(cfPtr); tmp = (char *)malloc(fl*2);
    memset(tmp, 0x0, fl*2);
    Base64Encode(buf, fl, tmp); sprintf(buf, "--%s\nContent-Type: application/octet-stream; name=\"%s\"\nContent-Transfer-Encoding: base64\nContent-Description: attachment; filename=\"%s\";\n\n%s\n", bin, p, p, tmp);
    printf(buf);
    send(csocket, buf, strlen(buf), 0);
    free(tmp);
    free(buf);
    }else{
    perror("Open file failed:");
    }
    p += strlen(p) + 1;
    }
    }//发送邮件
    int xmail_send(XMAIL_NODEPTR M){
    SOCKETAPI SocketAPI;
    char smtp_addr[255]={0};
    GetIPAddress(M->smtp_addr, smtp_addr);
    SOCKET csocket = SocketAPI.InitClient(smtp_addr, M->smtp_port);
    struct sockaddr_in dest_addr;
    int pl;
    char buf[MSGMAXLENGTH*10], tmp[MSGMAXLENGTH];
    if (!csocket){
    perror("InitClient");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    if (strstr(buf, "ESMTP")){//如果是esmtp服务器,发送EHLO问候
    sprintf(buf, "EHLO %s%c%c", "XDream", 13, 10);//XDream即本地主机名
    }else{//如果是smtp服务器,发送HELO问候
    sprintf(buf, "HELO %s%c%c", "XDream", 13, 10);
    }
    printf(buf);
    pl = send(csocket, buf, strlen(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Send");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    sprintf(buf, "AUTH LOGIN%c%c", 13, 10);//告诉esmtp服务器准备登陆了
    printf(buf);
    pl = send(csocket, buf, strlen(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Send");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    sprintf(buf, "%s%c%c", M->user_name, 13, 10);//发送用户名
    printf(buf);
    pl = send(csocket, buf, strlen(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Send");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    sprintf(buf, "%s%c%c", M->user_pwd, 13, 10);//发送密码
    printf(buf);
    pl = send(csocket, buf, strlen(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Send");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    sprintf(buf, "MAIL FROM:%s%c%c", M->fromaddr, 13, 10);//告诉服务器邮件从哪里来
    printf(buf);
    pl = send(csocket, buf, strlen(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Send");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    sprintf(buf, "RCPT TO:%s%c%c", M->toaddr, 13, 10);//告诉邮件服务器邮件到哪里去
    pl = send(csocket, buf, strlen(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Send");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    sprintf(buf, "DATA%c%c", 13, 10);//告诉服务器准备发送数据包了
    printf(buf);
    pl = send(csocket, buf, strlen(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Send");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    memset(tmp, 0x0, sizeof(tmp));
    Binary(tmp);
    sprintf(buf, "From: %s\nTo: %s\nX-Mailer: XDream\nSubject: %s\nMIME-Version: 1.0\nContent-Type:multipart/alternative; boundary=\"%s\"\n\n", M->s_fromaddr, M->s_toaddr, M->subject, tmp);//发送MIME头
    printf(buf);
    send(csocket, buf, strlen(buf), 0);
    sprintf(buf, "--%s\nContent-Type: text/plain; Charset=GB2312\n\n%s\n--%s\nContent-Type: text/html; Charset=GB2312\n\n%s\n", tmp, M->text, tmp, M->html);//发送txt和html文挡
    printf(buf);
    send(csocket, buf, strlen(buf), 0);
    x_sendfile(M->attach, csocket, tmp);//发送附件
    sprintf(buf, "--%s--%c%c", tmp, 13, 10);
    printf(buf);
    send(csocket, buf, strlen(buf), 0);
    sprintf(buf, ".%c%c", 13, 10);//告诉服务器发送完毕
    printf(buf);
    pl = send(csocket, buf,strlen(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Send");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    sprintf(buf, "QUIT%c%c", 13, 10);//跟他说我准备走了
    printf(buf);
    pl = send(csocket, buf, strlen(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Send");
    return 0;
    }
    memset(buf, 0x0, sizeof(buf));
    pl = recv(csocket, buf, sizeof(buf), 0);
    if (pl==SOCKET_ERROR||pl==0){
    perror("Recv");
    return 0;
    }
    printf("%s\n", buf);
    closesocket(csocket);
    return 1;
    }int main(){
    XMAIL_NODE M;
    char *user_name = "islongtime";//用户名
    char *user_pwd = "iwaitfor";//密码
    char *filePath[] = {"hello.c", "hell.cpp", "mail.c", "mail.cpp", "Server.c", "Server.cpp"};//附件数组
    int i, sl = 0;
    char buf[MSGMAXLENGTH];
    memset(&M, 0x0, sizeof(XMAIL_NODE));
    strcpy(M.smtp_addr, "smtp.sina.com.cn");
    M.smtp_port = 25;
    Base64Encode(user_name, strlen(user_name), M.user_name);//加密一下用户名
    Base64Encode(user_pwd, strlen(user_pwd), M.user_pwd);//加密一下密码
    strcpy(M.fromaddr, "[email protected]");
    strcpy(M.toaddr, "[email protected]");
    strcpy(M.s_fromaddr, "islongtime<[email protected]>");
    strcpy(M.s_toaddr, "iamhere<[email protected]>");
    strcpy(M.subject, "This a esmtp mail from FreeBSD");
    M.text = "FreeBSD is the best best best operate system";
    M.html = "<h2>FreeBSD</h2>";
    for (i=0;i<sizeof(filePath)/sizeof(char *);i++){
    memcpy(M.attach+sl, filePath[i], strlen(filePath[i]));
    sl += strlen(filePath[i])+1;
    }
    xmail_send(&M);
    return 0;
    }