I found the following function, which can send a mail :
bool sendmail( char * smtpserver, char * from, char * to, char * subject, char * msg )
{
int iProtocolPort = 0;
char szSmtpServerName[64] = "";
char szToAddr[64] = "";
char szFromAddr[64] = "";
char szBuffer[4096] = "";
char szLine[255] = "";
char szMsgLine[255] = "";
SOCKET hServer;
WSADATA WSData;
LPHOSTENT lpHostEntry;
LPSERVENT lpServEntry;
SOCKADDR_IN SockAddr;
// Load command-line args
lstrcpyA( szSmtpServerName, smtpserver );
lstrcpyA( szToAddr, to );
lstrcpyA( szFromAddr, from );
// Attempt to intialize WinSock (1.1 or later)
if ( WSAStartup( MAKEWORD( VERSION_MAJOR, VERSION_MINOR ), &WSData ) )
{
printf( "\nCannot find Winsock v%d.%d or later", VERSION_MAJOR, VERSION_MAJOR );
return false;
}
// Lookup email server's IP address.
lpHostEntry = gethostbyname( szSmtpServerName );
if ( !lpHostEntry )
{
printf( "\nCannot find SMTP mail server %s", szSmtpServerName );
return false;
}
// Create a TCP/IP socket, no specific protocol
hServer = socket( PF_INET, SOCK_STREAM, 0 );
if ( hServer == INVALID_SOCKET )
{
printf( "\nCannot open mail server socket!" );
return false;
}
// Get the mail service port
lpServEntry = getservbyname( "mail", 0 );
// Use the SMTP default port if no other port is specified
if ( !lpServEntry ) iProtocolPort = htons( IPPORT_SMTP );
else iProtocolPort = lpServEntry->s_port;
// Setup a Socket Address structure
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = iProtocolPort;
SockAddr.sin_addr = *( (LPIN_ADDR)*lpHostEntry->h_addr_list );
// Connect the Socket
if ( connect( hServer, ( PSOCKADDR ) &SockAddr, sizeof( SockAddr ) ) )
{
printf( "\nError connecting to Server socket!" );
return false;
}
// Receive initial response from SMTP server
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0), "recv() Reply" );
// Send HELO server.com
sprintf_s( szMsgLine, "HELO %s%s", smtpserver, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() HELO" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 开发者_C百科), "recv() HELO" );
// Send MAIL FROM: <sender@mydomain.com>
sprintf_s( szMsgLine, "MAIL FROM:<%s>%s", from, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() MAIL FROM" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() MAIL FROM" );
// Send RCPT TO: <receiver@domain.com>
sprintf_s( szMsgLine, "RCPT TO:<%s>%s", to, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() RCPT TO" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() RCPT TO" );
// Send DATA
sprintf_s( szMsgLine, "DATA%s", CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() DATA" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() DATA" );
// Send Subject
sprintf_s( szBuffer, "Subject: %s\n", subject );
Check( send( hServer, szBuffer, strlen( szBuffer ), 0 ), "send() Subject" );
//Send From
sprintf_s( szBuffer, "From: %s\n", from );
Check( send( hServer, szBuffer, strlen( szBuffer ), 0 ), "send() From" );
//Send To
sprintf_s( szBuffer, "To: %s\n\n", to );
Check( send( hServer, szBuffer, strlen( szBuffer ), 0 ), "send() To" );
//Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() Attachment" );
sprintf_s( szMsgLine, "%s%s", msg, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() message-line" );
// Send blank line and a period
sprintf_s( szMsgLine, "%s.%s", CRLF, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() end-message" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() end-message" );
// Send QUIT
sprintf_s( szMsgLine, "QUIT%s", CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() QUIT" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() QUIT" );
// Close server socket and prepare to exit.
closesocket( hServer );
WSACleanup();
return true;
}
I am making an SQL query, and i would like to send the result in an email, but the result can be more than one line. So i don't know, how could i send the whole result at once. The result of the SQL query will be stored in a struct( but if someone has a better a idee then i'm listening :) ). So my question is, if is there a way to send this struct in email? Or how can i send every line which i get as a result in an email?
Thanks!
At the side you would like to send your structure:
// All sorts of initializations and stuff
memcpy(yourbuffer,&yourstructure,sizeof(yourbuffer));
At the other side:
// Trivial stuff like receiving your buffer :-)
memcpy(&yourstructure,yourbuffer,sizeof(yourstructure));
To answer your first question, if you want to send a struct through a socket, first you have to serialize it. In particular, the bytes of integers may not be in the same order on the destination machine. There are lots of protocols for serializing data such as ASN.1 and JSON. For C structs you would be better using something like msgpack or protobufs. After serializing the data, you have a byte array which can simple be sent through the socket one chunk at a time. Generally, you would also have a protocol wrapped around that which could be as simple as:
SENDBUF 437\r\n
GSUOHD*)*IHENHD{@DNJDPOJDPJONK:ND{D@O LDK?ND(G(OBDO*U|GR(G(DIU:OBD
Basically it is a command string, followed by the number of bytes in this packet followed by carriage return, linefeed. This is a typical protocol style used by HTTP, memcache and many others. After the linefeed character, you would collect the next n bytes (437 in the example) at the end of your input buffer. Since many structs would be more than one packet you could have BEGIN and END commands, or you could simply close the socket to mark the end of a struct.
The receiving process would collect bytes until the end of the struct, then deserialize it.
If you use a library like ZeroMQ, that will simplify the socket handling, but you would still have to deal with serializing and deserializing structs.
精彩评论