Topic : Socket Programming
Author : Vijay Mukhi
Page : << Previous 8  Next >>
Go to page :


sent and then we send our caller bogus information about ourselves. What we should have done was check exactly what he'd sent us and then react accordingly, but we don't care enough!!

That's about all there is to it.

The SMTP Server...

E-mail has changed the way we work, communicate and interact with people around us. It's cheaper than snail mail, more reliable and infinitely faster. E-mail is just another one of those Internet protocols that's made our lives so much easier and I guess it's only fitting that we tackle this protocol next.

E-mail is actually handled using two protocols; SMTP and POP3. SMTP or the Simple Mail Transfer Protocol is used to shoot the message across the vast expanse of the Internet. POP3 or the Post Office Protocol -3 is used by our E-mail clients to retrieve the mail from our service provider's mail server.

SMTP is indeed very simple. It's just a bunch of words we keep shooting at the SMTP server which tells it what we expect of it and where we want this mail to go. It is a far-cry from other protocols you might find as you stumble you're way through the hundreds of RFC's littering the 'net.

E-Mail (or SMTP - Simple Mail Transfer Protocol)

smtp.cpp

#include <windows.h>
#include <stdio.h>
void abc(char *p)
{       FILE *fp=fopen("z.txt","a+");
        fprintf(fp,"%s\n",p);
        fclose(fp);
}
struct sockaddr_in A;WSADATA W;SOCKET S;struct hostent *H;
char aa[100];int i;char R[10000];
int _stdcall WinMain(HINSTANCE ii, HINSTANCE j, char *k, int l)
{
  WSAStartup (0x101, &W);
  
  S=socket(AF_INET, SOCK_STREAM,0);

  A.sin_family=AF_INET;
  A.sin_port = htons(25);
  H=gethostbyname("giasbm01.vsnl.net.in");
  A.sin_addr.s_addr=*((unsigned long *) H->h_addr);
  i=connect(S,(struct sockaddr *) &A,sizeof(A));
  
  i=recv(S,R,10000,0);
  sprintf(aa,"recv %d R %s",i,R);
  abc(aa);
  strset(aa,' ');
  strcpy(R,"HELO vijay.com\r\n");
  
  i=send(S,R,strlen(R),0);
  
  i=recv(S,R,10000,0);
  sprintf(aa,"recv %d R %s",i,R);
  abc(aa);
  strset(aa,' ');
  
  strcpy(R,"MAIL FROM:<vijay1@giasbm01.vsnl.net.in>\r\n");
  i=send(S,R,strlen(R),0);
  
  i=recv(S,R,10000,0);
  sprintf(aa,"recv %d R %s",i,R);
  abc(aa);
  strset(aa,' ');
  
  strcpy(R,"RCPT  TO:<ravi@giasbm01.vsnl.net.in>\r\n");
  i=send(S,R,strlen(R),0);
  
  i=recv(S,R,10000,0);
  sprintf(aa,"recv %d R %s",i,R);
  abc(aa);
  strset(aa,' ');
  
  strcpy(R,"DATA\r\n");
  i=send(S,R,strlen(R),0);
  
  i=recv(S,R,10000,0);
  sprintf(aa,"recv %d R %s",i,R);
  abc(aa);
  strset(aa,' ');  
  
  strcpy(R,"TO: aaa.com\r\n");
  i=send(S,R,strlen(R),0);
  
  strcpy(R,"FROM: vijay1@giasbm01.vsnl.net.in\r\n");
  i=send(S,R,strlen(R),0);
  
  strcpy(R,"DATE: 10 Jan 95 13:24 PST\r\n");
  i=send(S,R,strlen(R),0);
  
  strcpy(R,"MESSAGE_ID: <123@e.com>\r\n");
  i=send(S,R,strlen(R),0);
  
  strcpy(R,"Hello\r\n");
  i=send(S,R,strlen(R),0);
  
  strcpy(R,"How are you\r\n");
  i=send(S,R,strlen(R),0);
  
  strcpy(R,".\r\n");
  i=send(S,R,strlen(R),0);
  
  i=recv(S,R,10000,0);
  sprintf(aa,"recv %d R %s",i,R);
  abc(aa);
  strset(aa,' ');
  
  strcpy(R,"QUIT\r\n");
  i=send(S,R,strlen(R),0);
  
  i=recv(S,R,10000,0);
  sprintf(aa,"recv %d R %s",i,R);
  abc(aa);

  return 0;
}



Most the of the program should be quite familiar by now. We've been a little lazy and we have omitted the callback function. Now the program will start working as soon as you execute it.

The function WSAStartup() is the same as before and so it most of the other initialisation code. The function socket()is exactly the same and so is the first member of the structure A. It's from the second member onwards that we start seeing some changes.

The SMTP protocol is on Port 25 and that's why A.sin_port is set to 25.

When you're surfing on the Internet, you don't usually need to know the IP address of a site to visit it. All you do is type in it's domain name and the browser does the rest. The code that follows htons shows you how it all really works.

H is a pointer to a structure which looks like hostent. Gethostbyname returns a pointer to a structure which looks like hostent and it fills up that structure with valuable information about the site within it's parenthesis.

This is what the structure looks like...


struct hostent
{
    char FAR *h_name;                   //official name of host
    char FAR * FAR *h_aliasses;         // alias list
    short h_addrtype;                   //host address type
    short h_length;                     //length of address
    char FAR * FAR * h_addr_list;       //list of addresses
#define h_addr *h_addr_list[0];       //first member of the list of                          //address .i.e. server address
};



The only member we're interested in right now is h_addr which is the site's IP address. This IP address is stored in A.sin_addr.s_addr. That's how we convert a URL into an IP address

The name we've given gethostbyname is the name of the mail server. It's the name after the @ sign in the email address and in our case it's giasbm01.vsnl.net.in.

Now comes the actual SMTP protocol commands. SMTP and POP3 both work in lockstep with the server at the other end. This means that the client sends one command and then it waits for a response from the server and vice-versa. The conversation does not proceed until an appropriate answer is received.

The first command we have to send the server is HELO (in CAPS and yes, it is HELO, not HELLO). The command is followed with the name of the computer we're coming from. The domain name doesn't have to exist because it's rarely checked and we've sent vijay.com as our domain.

After receiving our HELO, the server sends us some bytes too. These are caught by the receive and stored in the file z.txt. Check them out too.

After receiving the server's response, we send it the words MAIL FROM: < Vijay1@giasbm01.vsnl.net.in>\r\n. Vijay1@giasbm01.vsnl.net.in is our email address and this string appears in the Mail From field in your mail clients window. This too is not checked by the server and thus can be anything at all. We've sent mails to people with our return address as bgates@microsoft.com!!!

After capturing the servers response we send another bit of information to the server; RCPT TO: <e-mail address>\r\n where <e-mail address > is the email address of the person you want this message to go to. This is one data field which must be correct or the email will never reach it's destination.

It's only after RCPT TO: that our actual message starts. We send the server the word DATA and then wait for the servers acknowledgment. Once we have it, we can start the actual message information. The message ends when the server encounters a '.' (Period) all by itself on a fresh line.

The TO:, FROM:, DATE and MESSAGE ID: fields can also be filled up and they usually are, thought it's not compulsory. The Message ID is any old random number.

The actual email is then sent, line by line and the message ends with a period on a line all by itself.

Once we're through sending our mail we send a QUIT, terminating the session. If we had more than one mail to send, we'd again start with the MAIL FROM field.

Now lets tackle the other side of e-mails, POP3. POP3 is the protocol used to retrieve a mail from the POP3 server, the server where your mail eventually lands up. Lets check the code out first.

pop3.cpp

#include <windows.h>
     #include <stdio.h>
     void abc(char *p)
     {       FILE *fp=fopen("z.txt","a+");
             fprintf(fp,"%s\n",p);
             fclose(fp);
     }
     struct sockaddr_in A;
     WSADATA W;
     SOCKET S;
     char aa[60000];
     int i;
     struct hostent *H;
     char R[60000];
     int _stdcall WinMain(HINSTANCE ii, HINSTANCE j, char * k, int l)
     {
       WSAStartup (0x101, &W);
       S = socket(AF_INET, SOCK_STREAM,0);
       A.sin_family=AF_INET;
       A.sin_port = htons(110);
       H=gethostbyname("giasbm01.vsnl.net.in");
       A.sin_addr.s_addr=*((unsigned long *) H->h_addr);
       i=connect(S,(struct sockaddr *) &A,sizeof(A));
       sprintf(aa,"connect %d",i);
       abc(aa);
       i=recv(S,R,10000,0);
       sprintf(aa,"recv %d R %s",i,R);
       abc(aa);


Page : << Previous 8  Next >>