开发者

How to send a struct through socket?

开发者 https://www.devze.com 2023-04-08 19:43 出处:网络
I found the following function, which can send a mail : bool sendmail( char * smtpserver, char * from, char * to, char * subject, char * msg )

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号