[Previous] [Contents] [Next]
Lesson 5:
A Winsock UDP receiver
Introduction
This
is the
easiest lesson yet. A UDP receiver binds a socket to an interface and then
calls a function that waits for a UDP packet, that’s it.
Initialization and socket creation
You learned about
the initialization process in Lesson 2 and the UDP socket creation in Lesson 4,
so this won’t be too hard:
// author:
frenchwhale (http://frenchwhales_site.tripod.com) #include
<winsock.h> #include
<stdio.h> #include
<stdlib.h> #include
<string.h> int
main(int argc, int **argv) { WSADATA wsda; // Structure to store info // returned from
WSAStartup char szMessage[512]; int iMessageLen; int ret; char szAddress[64]; int iPort; SOCKET s; //
Our TCP socket handle SOCKADDR_IN addr, // The local interface address remote_addr; // The sender's address int iRemoteAddrLen; // Contains the length of remte_addr, passed to recvfrom // Check arguments if(argc != 2 || (argc==2 && strcmp((char *)
&argv[1][0], "/?")==0)) { printf("wsudprcv port\n"); printf(" port:
the port the server should listen to\n"); exit(1); } // Get the remote port iPort = atoi((char *) &argv[1][0]); if(iPort<0 || iPort>65563) { printf("Invalid port number!
(%s)\n", argv[2]); exit(1); } iMessageLen = 512; // Set to the length of szMessage buffer // Load version 1.1 of Winsock WSAStartup(MAKEWORD(1,1), &wsda); // Create an 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"); |
Binding, receiving and cleanup
In order to
receive any packets on a socket, it has to be bound to an interface. All this
is discussed thoroughly in Lesson 3, but I will include the function declaration
here, just for review:
int bind(SOCKET s, struct sockaddr FAR *addr,
int addrlen);
Where s is the socket handle, addr is a pointer to a sockaddr structure containing the local interface
address and port number and addrlen is the length of this structure. Remember
that you usually bind a socket to INADDR_ANY to listen on all interfaces.
The other function
we will encounter is recvfrom, declared as:
int recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen);
Where s is the socket handle, buf is a pointer to a buffer where the UDP
data will be stored, len is the length of the buffer, flags specifies some flags that should be used
(we won’t use any, just set it to 0), from is a pointer to a structure where the address of the
sender will be stored and lastly, fromlen is a pointer to an int containing the length of the sockaddr structure.
This part of the
code binds the socket, waits for a packet,
prints the content of it and then cleans up:
// Fill in the interface information
printf("Binding socket...");
addr.sin_family = AF_INET;
addr.sin_port = htons(iPort);
addr.sin_addr.s_addr = INADDR_ANY;
if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR)
{
printf("Error\nCall to bind(s, (struct sockaddr *) &addr, sizeof(addr));
failed with:\n%d\n", WSAGetLastError());
exit(1);
}
printf("OK\n");
// Ready to receive data
printf("Waiting for packets (Press Ctrl-C to exit)...");
iRemoteAddrLen = sizeof(remote_addr);
ret = recvfrom(s, szMessage, iMessageLen, 0, (struct sockaddr *)
&remote_addr, &iRemoteAddrLen);
if(ret == SOCKET_ERROR)
{
printf("Error\nCall to recvfrom(s, szMessage, iMessageLen, 0,
(struct sockaddr *) &remote_addr, &iRemoteAddrLen); failed
with:\n%d\n", WSAGetLastError());
exit(1);
}
printf("Packet received\n");
iMessageLen = ret; // Length
of the data received
szMessage[iMessageLen] = '\0'; //
Convert to cstring
printf("\"%s\" received from %s\n", szMessage,
inet_ntoa(remote_addr.sin_addr));
closesocket(s);
WSACleanup();
return 0; } |
Source code for Lesson 5:
n WSUDPRCV.C – Listens for a UDP packet to arrive at a specified port.
[Previous] [Contents] [Next]