                  _________________

                 /_               /\

                  \/  _______    /  \

                  /  /      /   /   /

                 /  /______/   /   /

                /           __/   /

               /  _______   \  __/

              /  /      /   /  \

             /  /______/   /   /

           _/             /   /

          /______________/   /       BLACK SUN RESEARCH FACILITY

          \              \  /      	   HTTP://BLACKSUN.BOX.SK

           \______________\/

    WINDOWS INTERNET PROGRAMMING {part 2}

    =================================================

       WRITTEN BY                 [ cos125@hotmail.com                :E-MAIL    ]

               BINARY RAPE        [ 114603188                         :ICQ#      ]

                                  [ www.geocities.com/wininetprogram  :WEB SITE  ]

                                  [ http://blacksun.box.sk            :TURORIALS ]

    Thanks to cyberwolf for letting me write this and BSRF for releasing it.

    Disclaimer

    None of the information or code in this tutorial is meant to be used

    against others

    or to purposely damage computer systems and/or cause any loss of or

    damage to property.

    Further more, neither myself or any other contributor to, or member

    of, the Blacksun

    research Facility (BSRF) can be held responsible for damage or loss

    of property to

    computer systems as a result of this tutorial.

    In this tutorial the code is provided as a learning aid so you can see

    how its done

    its not meant for you to use against yourself or others.

    If you don't agree with any of this then please stop reading......

    now!

    CONTENTS

    1.  Introduction

    2.  UNIX and Windows

    3.  Error Codes

    4.  Port Numbers

    5.  Include Files

       - 5.1 socket()

        -5.2 bind()

        -5.3 connect()

        -5.4 listen()

        -5.5 accept()

        -5.6 gethostname()

    6.  Common Functions

    7.  Renamed Functions

    8.  Blocking Routines

    9.  Additional Functions

    10. Porting Code

        -10.1 DNS Program

        -10.2 Streaming Server

        -10.3 Streaming Client

    11. Planning

    12. Last Words

        APPENDIXES

        A - The Compiler

    ______________________

    1.0 INTRODUCTION

    In the last part in this series of tutorials I discussed windows sockets

    programming using

    the winsock API and in that document I mentioned that the windows Sockets

    implementation is

    based on the Berkeley Sockets idea, therefore socket programming on

    systems such as UNIX

    and Linux, which are also based on the Berkeley API would be quiet

    similar. This aids us

    in porting from platform to platform, making it easy to move whole

    programs from UNIX to

    windows in a very short time.

    This tutorial will discuss and illustrate the differences in code and

    functions between the

    platforms and sample source code and applications will be provided

    to show how to port the

    applications piece by piece.

    I suggest that you first read Part 1 in this series of tutorials and

    also Bracaman's basic

    UNIX sockets tutorial, also available from blacksun.box.sk and also

    from code.box.sk.

    Any add on information for this tutorial and updates are available as

    usual from:

    http://www.geocities.com/winnetprogram.

    2.0 UNIX AND WINDOWS

    =====================

    Unix and Windows handle sockets differently, UNIX treats sockets the

    same as a file handle

    which is a small integer while in windows it is an unsigned type called

    SOCKET.

    So from the start UNIX and windows actually think of there respective

    sockets differently.

    To best explain the differences the following is an exert from bracamans

    tutorial and

    describes sockets from the Unix point of view:

    "In a very simple way, a socket is a way to talk to other computer.

    To be more precise, it's a way to talk to other computers using standard

    Unix file

    descriptors.

    In Unix, every I/O actions are done by writing or reading to a file

    descriptor. A file

    descriptor is just an integer associated with an open file and it can

    be a network connection,

    a terminal, or something else."

    3.0 ERROR CODES

    =======================================

    In UNIX error codes are available trough the errno variable. In windows

    we use the function

    WSAGetLastError() to obtain these error codes.

    _________________________

    4.0 PORT NUMBERS

    =======================================

    In both Unix and Windows you define the port numbers by entering the

    destination port number

    as a parameter to the function htons(), however in winsock.h several

    port numbers are defined

    for common ports so that you can also use these.

    The following is a list of the default names and there relative port

    numbers:

    1.  IPPORT_ECHO             -  7

    2.  IPPORT_DISCARD          -  9

    3.  IPPORT_SYSTAT           -  11

    4.  IPPORT_DAYTIME          -  13

    5.  IPPORT_NETSTAT          -  15

    6.  IPPORT_FTP              -  21

    7.  IPPORT_TELNET           -  23

    8.  IPPORT_SMTP             -  25

    9.  IPPORT_TIMESERVER       -  37

    10. IPPORT_NAMESERVER       -  42

    11. IPPORT_WHOIS            -  43

    12. IPPORT_MTP              -  57

    5.0 INCLUDE FILES

    =======================================

    In UNIX there are a number of include files to use in socket programming,

    following is a

    list of these functions and related #include files:

    5.1 socket()

          [ #include <sys/types.h>  ]

          [ #include <sys/socket.h> ]

    5.2 bind()

          [ #include <sys/types.h>  ]

          [ #include <sys/socket.h> ]

    5.3 connect()

          [ #include <sys/types.h>  ]

          [ #include <sys/socket.h> ]

    5.4 listen()

          [ #include <sys/types.h>  ]

          [ #include <sys/socket.h> ]

    5.5 accept()

          [ #include <sys/socket.h> ]

    5.6 gethostname()

      [ #include <netdb.h>   ]

    You will need some general socket include files also in UNIX programming:

    #include <netinet/in.h>

    #include <arpa/inet.h>

    Your average list of include files at the top of a UNIX socket program

    would therefore

    look something like the following:

    #include <sys/types.h>

    #include <sys/socket.h>

    #include <netdb.h>

    #include <netinet/in.h>

    #include <arpa/inet.h>

    In windows the header file for socket and internet programming is contained

    in windows.h,

    therefore the top of a windows socket programming would look like this:

    #include <windows.h>

    The name of the header file for windows socket programming is winsock.h

    and including

    this file in your project as well wont cause any errors of course but

    there’s just no need.

    Windows programs also need to be linked to the file Wsock32.lib before

    they can be

    compiled.

    Consult your compilers documents for further information on this or

    proceed to Appendix 1

    - The compiler.

    6.0COMMON FUNCTIONS

    =======================================

    Both Unix and Windows sockets have a set of functions common to both

    platforms. These are

    mostly the functions dealing with TCP and UDP and all conversion functions

    and structures

    are the same for both platforms.

    For example htons() and inet_addr() are the same on both platforms,

    also so is the

    structures sockaddr and sockaddr_in.

    Here is a list of common functions.

    1.  Socket()

    2.  Bind()

    3.  Listen()

    4.  Connect()

    5.  Accept()

    6.  Send()

    7.  Recv()

    8.  Sendto()

    9.  Recvfrom()

    10. Gethostname()

    7.0 RENAMED FUNCTIONS

    =======================================

    There are some functions which exist in both windows and UNIX socket

    programming but

    during the conversion the names have changed slightly.

    The following table contains a comparison of renamed functions in windows

    and UNIX.

    	+===============+==================+

    	| Unix Function | Windows Function |

    	+===============+==================+

    	|    close()    |   closesocket()  |

    	+---------------+------------------+

    	|    ioctl()    |   ioctlsocket()  |

    	+---------------+------------------+

    	|     read()    |      recv()      |

    	+---------------+------------------+

    	|    write()    |      send()      |

    	+---------------+------------------+

     FIG 1. - Comparison of Windows and Unix Socket functions.

    8.0 BLOCKING ROUTINES

    =======================================

    In windows you can use blocking routines but they are not recommended.

    In windows 3.1

    using the event driven paradigm it is possible to have a blocked operation

    disturbed

    by other event driven activity.

    Soon you will not be able to have blocking routines in Winsock applications

    so it is

    not recommended you use them at all in this scenario as this would

    limit distribution

    possibilities.

    9.0 ADDITIONAL FUNCTIONS

    =======================================

    In windows there are some functions which aren't seen in UNIX sockets.

    In every

    windows socket program you must call WSAStarup() before you can call

    any socket

    functions or use any code.

    Additionally every WSAStartup() function has a corresponding WSACleanup()

    which

    shuts down the Winsock and cleans up after us.

    Every Windows socket program must contain both of these functions.

    10.0 PORTING CODE

    =======================================

    Now that we have discussed the different parts of the program in Unix

    and its relevant

    Windows parts we can look at some real code.

    [ 10.1 ] DNS PROGRAM

    The first program we come across is Bracamans DNS application. Here’s

    the Unix Code.

    /* <---- SOURCE CODE STARTS HERE ----> */

    #include <stdio.h>

    #include <netdb.h>   /* This is the header file needed

    for gethostbyname() */

    #include <sys/types.h>

    #include <sys/socket.h>

    #include <netinet/in.h>

    int main(int argc, char *argv[])

    {

      struct hostent *he;

      if (argc!=2){

         printf("Usage: %s <hostname>\n",argv[0]);

         exit(-1);

      }

      if ((he=gethostbyname(argv[1]))==NULL){

         printf("gethostbyname() error\n");

         exit(-1);

      }

      printf("Hostname : %s\n",he->h_name);  /* prints the hostname

    */

      printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr)));

    /* prints IP address */

    }

    /* <---- SOURCE CODE ENDS HERE ----> */

    This is a very small but still a very useful program. If we attempt

    to compile this

    right away under Microsoft Visual C++ We will get an error saying that

    it can not

    find an include file, so our first duty is to remove all of the Unix

    Socket include

    files and replace them with the line:

    #include <windows.h>

    remembering to leave stdio.h right where it is.

    When I tried compiling it now I got several more errors so I changed

    the

    main() fuction from what it is above to:

    void main(int argc, char **argv) and the program then compiled.

    However I then got several linker errors. Remember when socket programming

    on windows

    you must link to the file Wsock32.lib.

    After I linked to the proper .lib file the program compiles perfectly,

    without the

    need to touch a single line of the socket code!!

    This is how compatible different platforms can be with socket code,

    however this is a

    very small program and this is not usually the case. The following

    is the windows

    source code for the port of Bracamans DNS program.

    Remember you will get an error unless you include WSAStartup() and WSACleanup()!!

    /* <---- SOURCE CODE STARTS HERE ----> */

    #include <windows.h>

    #include <stdio.h>

    int main(int argc, char *argv[])

    {

      WSADATA  wsdata;

      WSAStartup(0x0101,&wsdata);

      struct hostent *he;

      if (argc! = 2)

      {

         printf("Usage: %s hostname\n",argv[0]);

         return -1;

      }

      if ((he = gethostbyname(argv[1])) == NULL)

      {

         printf("gethostbyname() error\n");

         return -1;

      }

      printf("Hostname : %s\n",he->h_name);

    /* prints the hostname */

      printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr)));

    /* prints IP address */

      WSACleanup();

      return -1;

    }

    /* <---- SOURCE CODE ENDS HERE ----> */

    This program has almost as few lines as the UNIX alternative and requires

    practically

    no porting at all!

    Like I said you wouldn’t usually have a program that runs on windows

    with such little altering.

    Lets discuss porting Bracamans TCP streaming server.

    [ 10.2 ] STREAMING SERVER

    /* <---- SOURCE CODE STARTS HERE ----> */

    #include <stdio.h>

    /* These are the usual header files */

    #include <sys/types.h>

    #include <sys/socket.h>

    #include <netinet/in.h>

    #define PORT 3550   /* Port that will be opened */

    #define BACKLOG 2   /* Number of allowed connections */

    main()

    {

      int fd, fd2; /* file descriptors */

      struct sockaddr_in server; /* server's address information */

      struct sockaddr_in client; /* client's address information */

      int sin_size;

      if ((fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 ){  /* calls

    socket() */

        printf("socket() error\n");

        exit(-1);

      }

      server.sin_family = AF_INET;

      server.sin_port = htons(PORT);   /* Remember htons()

    from "Conversions" section? =) */

      server.sin_addr.s_addr = INADDR_ANY;  /* INADDR_ANY puts

    your IP address automatically */

      bzero(&(server.sin_zero),8); /* zero the rest of the structure

    */

      if(bind(fd,(struct sockaddr*)&server,sizeof(struct sockaddr))==-1){

    /* calls bind() */

          printf("bind() error\n");

          exit(-1);

      }

      if(listen(fd,BACKLOG) == -1){  /* calls listen() */

          printf("listen() error\n");

          exit(-1);

      }

    while(1){

      sin_size=sizeof(struct sockaddr_in);

      if ((fd2 = accept(fd,(struct sockaddr *)&client,&sin_size))==-1){

    /* calls accept() */

        printf("accept() error\n");

        exit(-1);

      }

      printf("You got a connection from %s\n",inet_ntoa(client.sin_addr)

    ); /* prints client's IP */

      send(fd2,"Welcome to my server.\n",22,0); /* send to the client

    welcome message */

      close(fd2); /*  close fd2 */

    }

    }

    /* <---- SOURCE CODE ENDS HERE ----> */

    Well lets try and compile shall we...

    Straight away we should clear the obvious problems, link to Winsock32.lib

    and

    only include windows.h and stdio.h.

    Having done so we receive 2 errors, the first pertains to bzero which

    we do not

    have in our little program so we are going to just remove the line

    that contains

    it. Once we do so we now have only 1 error, woohoo!

    This error tells us that the function close() is not a valid identifier

    which is

    what I said earlier, close() has been replaced by closesocket() in

    windows so we

    change that as well to closesocket().

    We run this program and we recieve a socket error :(. But remember we

    never entered

    WSAStartup() and WSACleanup() in this program so we have to do that

    first and then

    our program will work :).

    If you run the program the command prompt should remain blank, just

    leave the program

    as it is now and move onto the next section to figure out where to

    go from here!!

    First of course here’s the Windows code for the port ;).

    /* <---- SOURCE CODE STARTS HERE ----> */

    #include <stdio.h>

    /* These are the usual header files */

    #include <windows.h>

    #define PORT 3550         /*

    Port that will be opened */

    #define BACKLOG 2         /*

    Number of allowed connections */

    main()

    {

      WSADATA  wsdata;

      WSAStartup(0x0101,&wsdata);

      int fd, fd2;        /* file

    descriptors */

      struct sockaddr_in server;      /* server's

    address information */

      struct sockaddr_in client;      /*

    client's address information */

      int sin_size;

      if ((fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 )

    /* calls socket() */

      {

        printf("socket() error\n");

        exit(-1);

      }

      server.sin_family       = AF_INET;

      server.sin_port

    = htons(PORT);      /* Remember htons() from "Conversions"

    section? =) */

      server.sin_addr.s_addr  = INADDR_ANY;

    /* INADDR_ANY puts your IP address automatically */

      if(bind(fd,(struct sockaddr*)&server,sizeof(struct sockaddr))==-1)

    /* calls bind() */

      {

          printf("bind() error\n");

          exit(-1);

      }

      if(listen(fd,BACKLOG) == -1)      /*

    calls listen() */

      {

          printf("listen() error\n");

          exit(-1);

      }

    while(1)

      {

      sin_size=sizeof(struct sockaddr_in);

      if ((fd2 = accept(fd,(struct sockaddr *)&client,&sin_size))

    == -1)         /* calls accept()

    */

      {

          printf("accept() error\n");

          exit(-1);

      }

      printf("You got a connection from %s\n",inet_ntoa(client.sin_addr)

    );      /* prints client's IP */

      send(fd2,"Welcome to my server.\n",22,0);

    /* send to the client welcome message */

      closesocket(fd2);       /*

    close fd2 */

       WSACleanup();

          return -1;

    }

    }

    /* <---- SOURCE CODE ENDS HERE ----> */

    [ 10.3 ] STREAMING CLIENT

    /* <---- SOURCE CODE STARTS HERE ----> */

    #include <stdio.h>

    #include <sys/types.h>

    #include <sys/socket.h>

    #include <netinet/in.h>

    #include <netdb.h>        /*

    netbd.h is needed for struct hostent =) */

    #define PORT 3550   /* Open Port on Remote Host */

    #define MAXDATASIZE 100   /* Max number of bytes of data

    */

    int main(int argc, char *argv[])

    {

      int fd, numbytes;   /* files descriptors */

      char buf[MAXDATASIZE];  /* buf will store received text

    */

      struct hostent *he;

    /* structure that will get information about remote host */

      struct sockaddr_in server;  /* server's address information

    */

      if (argc !=2) {       /* this is

    used because our program will need one argument (IP) */

        printf("Usage: %s <IP Address>\n",argv[0]);

        exit(-1);

      }

      if ((he=gethostbyname(argv[1]))==NULL){ /* calls gethostbyname()

    */

        printf("gethostbyname() error\n");

        exit(-1);

      }

      if ((fd=socket(AF_INET, SOCK_STREAM, 0))==-1){  /* calls

    socket() */

        printf("socket() error\n");

        exit(-1);

      }

      server.sin_family = AF_INET;

      server.sin_port = htons(PORT); /* htons() is needed again */

      server.sin_addr = *((struct in_addr *)he->h_addr);  /*he->h_addr

    passes "*he"'s info to "h_addr" */

      bzero(&(server.sin_zero),8);

      if(connect(fd, (struct sockaddr *)&server,sizeof(struct sockaddr))==-1){

    /* calls connect() */

        printf("connect() error\n");

        exit(-1);

      }

      if ((numbytes=recv(fd,buf,MAXDATASIZE,0)) == -1){  /* calls

    recv() */

        printf("recv() error\n");

        exit(-1);

      }

          buf[numbytes]='\0';

          printf("Server Message: %s\n",buf); /*

    it prints server's welcome message =) */

          close(fd);   /* close fd =)

    */

    }

    /* <---- SOURCE CODE ENDS HERE ----> */

    That’s the source code for the Unix client and of course the windows

    one doesn't

    look very different.

    /* <---- SOURCE CODE STARTS HERE ----> */

    #include <windows.h>

    #include <stdio.h>

    #define PORT 3550       /* Open Port on

    Remote Host */

    #define MAXDATASIZE 100      /* Max number

    of bytes of data */

    int main(int argc, char *argv[])

    {

      WSADATA  wsdata;

      WSAStartup(0x0101,&wsdata);

      int fd, numbytes;      /* files descriptors

    */

      char buf[MAXDATASIZE];     /* buf will store

    received text */

      struct hostent *he;

    /* structure that will get information about remote host */

      struct sockaddr_in server;    /* server's address

    information */

      if (argc !=2) {

    /* this is used because our program will need one argument (IP) */

        printf("Usage: %s <IP Address>\n",argv[0]);

        exit(-1);

      }

      if ((he=gethostbyname(argv[1])) == NULL){ /* calls gethostbyname()

    */

        printf("gethostbyname() error\n");

        exit(-1);

      }

      if ((fd=socket(AF_INET, SOCK_STREAM, 0))==-1) /* calls socket()

    */

      {

        printf("socket() error\n");

        exit(-1);

      }

      server.sin_family  = AF_INET;

      server.sin_port    = htons(PORT);

    /* htons() is needed again */

      server.sin_addr    = *((struct in_addr *)he->h_addr);

    /*he->h_addr passes "*he"'s info to "h_addr" */

      if(connect(fd, (struct sockaddr *)&server,sizeof(struct sockaddr))==-1)

    /* calls connect() */

      {

        printf("connect() error\n");

        exit(-1);

      }

      if ((numbytes=recv(fd,buf,MAXDATASIZE,0)) == -1)

    /* calls recv() */

      {

        printf("recv() error\n");

        exit(-1);

      }

          buf[numbytes] = '\0';

          printf("Server Message: %s\n",buf);

    /* it prints server's welcome message =) */

          closesocket(fd);

    /* close fd =) */

          WSACleanup();

          return -1;

    }

    /* <---- SOURCE CODE ENDS HERE ----> */

    There’s actually no real difference with this port and the last. The

    same lines are

    changed and the same functions are included as before.

    Start the program by switching to its directory on the command line

    and typing

    streamclient.exe local host

    Where streamclient.exe is the name of the stream client program we just

    ported

    naturally :).

    Just make sure that the previous example, the streaming server is running

    and

    your away. The screen will print the line "Welcome to my server." Congratulations

    you’ve ported your first Unix Socket client and server to windows and

    you received

    a line of text back from your own server :).

    11.0 Planning

    =======================================

    When porting its probably best to go trough things like a check list

    before attempting

    to compile the bloody thing. Here’s a list of some recommendations

    to run trough first.

    1. Replace all network header files with windows.h or winsock.h.

    2. Make sure to add WSAStartup() and WSACleanup() before and after

    the code.

    3. Replace functions such as close() and ioctl() with windows counterparts.

    4. Take care of problems such as bzero() and add any windows specific

    features like

       default ports.

    With so few and simple operations like this it would be pretty damn

    easy to write

    a program that performs these actions for you, I doubt it would be

    complete but hey

    it would save you a lot of time in the long run, especially with larger

    applications.

    12.0 LAST WORDS

    ==============

    Well that’s it for this tutorial, or at least this part of it. More

    parts are planned so

    hopefully you should see them on blacksun soon :). This part covered

    the basics of

    windows programming, there was no point in writing about UNIX programming

    as bracaman

    has released a very good tutorial on basic UNIX sockets programming

    which is available

    from blacksun.box.sk and code.box.sk.

    I will be discussing Unix sockets again however in the next part of

    this tutorial but

    mostly in a porting sense. To see what’s planned for future parts so

    far just look down :).

    Part 2. -  GENERAL SOCKETS  - Porting to windows and cross

    platform code.

    Part 3.  -  RAW Sockets     - Have more

    control over packets with raw sockets.

    Part 4.  -  ADVANCED      - A real

    world example by building an internet communication suite.

    Part 5.  -  FINISHING OFF    - Putting it

    all together in one big program.

    So that’s what’s still to come, but I may change some of these future

    tutorials at any

    time before there released if I do so it will be to improve the series

    in my view and

    remember send me comments and suggestions and your ideas might also

    change the layout

    of following tutorials.

    Well thank you for reading this tutorial and visit my website to keep

    up to date with

    the series and for add on code and articles to the series.

    - BR ;)

    *FINAL NOTE*

    Id really like to thank Bracaman for everything including allowing me

    to use code from

    his tutorial and please remember that this tutorial should be read

    with his (after his

    1 even :P), so thanks for everything Bracaman it helped so much :).

    APPENDIX A - THE COMPILER

    All of the programs in this tutorial have been tested under Microsoft

    Visual C++ 6.0,

    im running Windows 2000 Professional edition and I have an Intel Pentium

    2.

    To set up the compiler for Winsock programming you need to link Wsock32.lib

    to your project.

    Under Visual C++ do the following.

    1. Select the File view tab.

    2. Right Click the files menu and go to Settings.

    3. Select the Link tab in Project Settings.

    4. Add Wsock32.lib to the list of .lib files and press ok.

    The winsock.h header file is included in windows.h so don’t worry about

    that.