2012-02-02 13 views
9

Ho appena iniziato a conoscere la programmazione dei socket e ho imparato a conoscere la winsock e ho raggiunto dei progressi. la mia domanda è fondamentalmente: voglio inviare e-mail, cosa devo fare?Invio di e-mail tramite C

punti da menzionare:

  1. ho imparato a conoscere l'inizializzazione di Winsock. Porta SMTP (25). creazione e connessione a socket con successo. Cosa dovrei fare ora?!!! (Sono bloccato qui)
  2. Non voglio un codice pronto per il lavoro. Voglio imparare. Quindi, sono necessari tutti i libri, le documentazioni, i tutorial o gli articoli consigliati.
  3. So che C non sa nulla di networking, vuol dire che devo scaricare alcune librerie? (Sto usando VS2010, Windows 7)

Ecco i link alle pagine che ho letto finora:

guida Winsock di base: http://msdn.microsoft.com/en-us/library/windows/desktop/ms737629(v=vs.85).aspx

Ho letto le prime 14 pagine di guida beej (non può postare il link, i nuovi utenti possono inviare un massimo di due collegamenti ipertestuali)

ho imparato a conoscere i tipi (WSADATA, addrinfo structure, sockaddr, SOCKET) e funzioni (WSAStartup(), WSACleanup(), getaddrinfo(), Shutdown(), WSAGetLastError(), socket(), ...)

e ho appena iniziato a leggere questo articolo su SMTPhttp://www.faqs.org/rfcs/rfc821.html

ecco quello che ho scritto fino ad ora:

#include <stdio.h> 
#include <WinSock2.h> 
#include <WS2tcpip.h> 

#pragma comment(lib, "Ws2_32.lib") // Applications that use Winsock must be linked with the Ws2_32.lib library file. 

#define HTTP_PORT "80" 
#define SMTP_PORT "25" 
#define HOSTNAME_PORT "101" 

/* 
All ports and web services names (which are string aliases of the ports 

can be found here: 
%WINDIR%\system32\drivers\etc\services 

*/ 

int main(void) 
{ 
    WSADATA wsdata; 
    int iresult, retval; //iresult : instant result 
    SOCKET connect_socket; 
    struct addrinfo *result, *ptr, hints; 

    iresult = WSAStartup(MAKEWORD(2, 2), &wsdata); 
    if(iresult != 0) printf("Initiation of Winsock succeeded.\n"); 
    else 
    { 
     printf("WinSock initialization failed..\n"); 
     WSACleanup(); 
     return 0; 
    } 

    if(LOBYTE(wsdata.wVersion) == 2 && HIBYTE(wsdata.wVersion) == 2) printf("winsock.dll is found.\n"); 
    else 
    { 
     printf("Can not find the required winsock.dll file.\n"); 
     WSACleanup(); 
     return 0; 
    } 

    ZeroMemory(&hints, sizeof(hints)); 
    hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 
    hints.ai_protocol = IPPROTO_TCP; // TCP connection (full duplex) 
    hints.ai_socktype = SOCK_STREAM; // Provides sequenced, reliable, two-way, connection-based byte streams 

    connect_socket = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol); 
    if(connect_socket == INVALID_SOCKET) 
    { 
     printf("Socket Creation failed..\n"); 
     WSACleanup(); 
     return 0; 
    } 
    else printf("Socket Creation Succeeded ..\n"); 
    WSACleanup(); 
    return 1; 
} 

am fuori rotta?

+0

Mi raccomando di leggere Stevens' eccellente libro "TCP/IP Illustrated", e anche la sua "Avanzate Programmazione nell'ambiente Unix ". Sì, lo so che dice Unix, ma è davvero un libro eccellente e 'winsock' è fondamentalmente un'implementazione dell'API socket BSD. – cha0site

risposta

3

Si dovrebbe dare un'occhiata a some examples on smtp via telnet :)

Fondamentalmente è necessario inserire in qualcosa di chiaro come questo:

HELO local.domain.name 
MAIL FROM: [email protected] 
RCPT TO: [email protected] 
DATA 
... 

EDIT secondo il this example, il codice dovrebbe essere:

// Not sure about this one, maybe just "\n" 
#define SEPARATOR "\n\r" 

int sendData(Socket *socket, const char *data) { 
    int iResult; 
    iResult = send(socket, data, (int) strlen(data), 0); 
    if(iResult == SOCKET_ERROR){ 
     // Do error handling as you like 
    } 
    return iResult; 
} 

sendData(socket, "HELO local.doman.name" SEPARATOR); 
sendData(socket, "MAIL FROM: [email protected]" SEPARATOR); 
sendData(socket, "RCPT TO: [email protected]" SEPARATOR); 
sendData(socket, "DATA" SEPARATOR); 
sendData(socket, "This is subject of my mail" SEPARATOR SEPARATOR); 
sendData(socket, "And this is text" SEPARATOR); 
sendData(socket, "." SEPARATOR); // Send mail 
+0

Ho eseguito qualcosa di simile, ma non riuscivo a capire cosa fare con quello? Intendo dove mettere questo testo? e perché? cosa significa "HELO" significa (penso di salutare il server)? – joker

+0

@joker mettilo in telnet: http://en.wikipedia.org/wiki/Telnet c'è persino un programma per questo in Windows chiamato lo stesso. – Flavius

+0

@joker: 'Nel comando HELO l'host che invia il comando identifica lo stesso ; il comando può essere interpretato come "Salve, sono " ' – cha0site

4

Si dovrebbe leggere come usare smtp su telnet. Dopo di che si può facilmente implementare esso ..

+0

grazie, ho iniziato a leggerlo proprio ora. Spero che questo aiuti – joker

+0

Ho letto la pagina a cui sei collegato. Ho imparato alcune cose, ma sembra essere obsoleto. Ho dovuto cercare il "menu di connessione" e la porta per aprire il server di posta yahoo (dal momento che 25 è entrato, la connessione fallisce) il tuo aiuto è molto apprezzato – joker

2

ti consiglierei di questo articolo:

SMTP Client - CodeProject

È possibile compilare sotto Linux e Windows anche.

+0

+1 puoi scrivere il tuo client SMTP, ma è sicuramente più facile da usare uno dei tanti che si possono trovare sul Interwebs. – JeremyP

+0

Inoltre è possibile controllare il codice sorgente dei client di posta open source come sendmail. – rkosegi

+0

+1, per una parte preziosa di informazioni :-) –

0

RFC 5321 è la specifica ufficiale per il protocollo SMTP di base.

RFC 2822 è la specifica ufficiale per il formato di base della posta elettronica.

Tenere presente che MOLTE RFC aggiuntive estendono le regole di base. Ad esempio, RFC 1651 estende SMTP, quindi è possibile implementare funzionalità aggiuntive, ad esempio l'autenticazione protetta tramite lo AUTH extension. E MIME (RFC 2045, 2046, 2047, 2048, e 2049) è comunemente usato nei moderni sistemi di posta elettronica per consentire gli allegati, HTML/RTF, ecc

Vai a IETF's website per vedere tutte le specifiche RFC disponibili utilizzati dalla maggior parte dei protocolli Interpet .

0
bytes_to_receive = sizeof(packet) 

received_bytes = 0; fare { received_bytes + = recv (tampone + received_bytes, bytes_to_receive - received_bytes) } while (received_bytes = bytes_to_receive!)

+0

Potresti elaborare più la tua risposta aggiungendo un po 'più di descrizione della soluzione che fornisci? – abarisone

Problemi correlati