[Previous] [Contents] [Next]

 

Lesson 4:
A Winsock UDP sender

 

[Fig. 4-1, a UDP packet being sent from the sender to the receiver]

 

Introduction

The UDP protocol is somewhat different from the TCP protocol, the most important difference is that it’s message-based, that is you don’t establish any “connections” to the receiver, you only send messages. The second difference is that UDP is an unreliable protocol, unlike TCP, UDP doesn’t guarantee that your information reaches its destination. You can compare UDP with the postal service, you aren’t guaranteed that the mail will reach its destination (although it often does). TCP however can be compared with a phone call, you exchange information simultaneously and you are guaranteed that the information is delivered.

 

Obtaining command-line arguments and initialization

You probably know this part of the code by now, but I’ll show it anyway, for completeness sake:

 

// author:           frenchwhale (http://frenchwhales_site.tripod.com)
//                   for the WinSock tutorial
//
// file name:        wsudpsnd.c
//
// description:      A UDP packet sender that sends a
//                   UDP packet containing a pre-specified
//                   message.
// Copyright 2002 frenchwhale
 

 

#include <winsock.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

#define MESSAGE         "This is an UDP message."

 

int main(int argc, int **argv)

{

   WSADATA wsda;        // Structure to store info

                             // returned from WSAStartup

 

   struct hostent *host;     // Used to store information

                                  // retreived about the server

 

   char szMessage[80];

   int iMessageLen;

   int ret;

 

   char szAddress[64];

   int iPort;

 

   SOCKET s;       // Our TCP socket handle

   SOCKADDR_IN addr;    // The host's address

 

   // Check arguments

   if(argc != 3 ||

      (argc==2 && strcmp((char *) &argv[1][0], "/?")==0))

   {

printf("wsudpsnd server port\n");

printf("   server: the server to send the packet to\n");

      printf("   port: the port on the remote server\n");

      exit(1);

   }

 

   // Copy the IP address

strcpy(szAddress, (char *) &argv[1][0]);

 

   // Get the remote port

   iPort = atoi((char *) &argv[2][0]);

 

if(iPort<0 || iPort>65563)

   {

printf("Invalid port number! (%s)\n", argv[2]);

      exit(1);

   }

 

   // Copy the pre-defined message into a buffer

strcpy(szMessage, MESSAGE);

 

   iMessageLen = strlen(szMessage);

 

   // Load version 1.1 of Winsock

 

WSAStartup(MAKEWORD(1,1), &wsda);

 

The code obtains the command-line arguments, checks if the port number is valid and initializes Winsock, if you aren’t familiar with these concepts, see Lesson 2.

 

Socket creation and resolving

Here comes the first major difference between the TCP client and the UDP sender, the socket creation:

 

   // Create a UDP socket

   printf("Creating socket...");

   s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

 

   // Error?

   if(s == SOCKET_ERROR)

   {

      printf("Error\nCall to socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); failed with:\n%d\n",       WSAGetLastError());

      exit(1);

   }

 

   printf("OK\n");

 

   // Fill in the host information

   addr.sin_family = AF_INET;

   addr.sin_port = htons(iPort);

   addr.sin_addr.s_addr = inet_addr(szAddress);

 

   if(addr.sin_addr.s_addr == INADDR_NONE) // The address wasn't in numeric

                                           // form, resolve it

   {

      host = NULL;

      printf("Resolving host...");

      host = gethostbyname(szAddress); // Get the IP address of the server

                                       // and store it in host

      if(host == NULL)

      {

         printf("Error\nUnknown host: %s\n", szAddress);

         exit(1);

      }

      memcpy(&addr.sin_addr, host->h_addr_list[0],

             host->h_length);

      printf("OK\n");

   }

 

The code creates a socket of the AF_INET family (for the TCP/IP protocol), the SOCK_DGRAM type (for a datagram-based socket) and IPPROTO_UDP protocol (tells Winsock to use the UDP protocol). The different family/type/protocol combinations can be found in Lesson 2, Fig 2-1. The reason for using IPPROTO_UDP is because it’s the only protocol you can use with AF_INET and SOCK_DGRAM. The resolving is done the same way as in the TCP client, you assume that the address is in numeric form (aaa.bbb.ccc.ddd) and if it doesn’t work, it resolves it using the resolving techniques learned in Lesson 2.

 

Sending and cleanup

Since a UDP socket is never connected to the receiver (you can connect it, but it’s unusual), you have to tell Winsock the address of the receiver in another way, this is done with the sendto function, which is declared as:

 

int sendto(SOCKET s, const char FAR *buf, int len, int flags, const struct sockaddr FAR *to, int tolen);

 

The first argument to sendto is the UDP socket you’re sending on, the second is a pointer to a buffer holding the data you want to send in the packet, the third is the length of the data, the fourth is some flags (just set it to 0), the fifth is a pointer to a sockaddr structure representing the address of the receiver and finally, the last argument is the length of the sockaddr structure.

When you use this function, you use the first four arguments as you would using send, the fifth and sixth arguments however are set to the address of the receiver and the address structure length.

Here’s the last part of the code:

 

   // Ready to send data

 

   printf("Sending packet...");

   ret = sendto(s, szMessage, iMessageLen, 0, (struct sockaddr *) &addr, sizeof(addr));

 

   if(ret == SOCKET_ERROR)

   {

      printf("Error\nCall to sendto(s, szMessage, iMessageLen, 0, (SOCKADDR_IN *) &addr, sizeof(addr)); failed with:\n%d\n", WSAGetLastError());

      exit(1);

   }

   printf("OK\n");

 

   printf("\"%s\" sent to %s\n", szMessage, szAddress);

 

   closesocket(s);

 

   WSACleanup();

 

   return 0;

}

 

The packet is sent, an error check is made, the socket is closed and WSACleanup is called.

 

 

Source code for Lesson 4:

n       WSUDPSND.C – Sends a UDP packet to a host containing a pre-specified message.

 

[Previous] [Contents] [Next]