![]() |
ANU College of Engineering and Computer Science
School of Computer Science
|
|
|
Computer NetworksSimple UDP programming exerciseThis is the first network programming exercise. The objective is to become familiar with how to write networking code in C under Linux (or most any modern Unix). There is a UDP "server" program running on the machine who's IP number is 192.168.X.254 (where X is the numeric part of the lab room number, eg. 113, 114 or 115) on the well-known UDP port 3310 (OK... well known to us, anyway). Whenever it receives a datagram on this port, it sends back a text message. The maximum length of the text message is 100 bytes including the terminating null. Part 1Your first task is to write a C program that will send a datagram to this server, receive the return message and print it out. To do this, you will need to know about a few "C" network library calls. In particular, you should read the man pages on the following routines and use them more-or-less is this order: Note: socket(2) means to read the documentation in the second section of the man pages by typing man 2 socket in a terminal window.socket(2) - provides a "file descriptor" paradigm to the networking code - this allows network connections to behave like files so that you _could_ use read() and write() etc. In our case, we want to use domain AF_INET (Internet), and type SOCK_DGRAM (for UDP datagrams). Protocol can be left as the default (0). gethostbyname(3) - may be useful here. It will return a pointer to a structure that contains the IP address (in binary) of its argument. The argument can be an IP address in dotted decimal notation, or a symbolic name. Alternatively, simply fill in the sin_addr.s_addr part of your struct sockaddr_in with the (byte order corrected) IP number - which is 0xc0a8XXfe in hexadecimal (convert each octet from decimal to hexadecimal and then concatenate them - XX is 71 for N113, 72 for N114, and 73 for N115). bind(2) - is not actually required for the first part, but is for the server part. It is used to bind a socket to an actual port, so that the UDP (or TCP etc.) code knows which process to deliver datagrams addressed for that port to. Sockfd is what socket(2) returns, my_addr is the address to bind to and addrlen is the length of the address structure. You will need to consult /usr/include/netinet/in.h to see what a sockaddr_in looks like. In particular, you will need to set sin_family to AF_INET. Also, don't forget that all network traffic needs to go in network byte order. You should use ntohs(), htons(), ntohl() and htonl() to convert between host and network byte orders for short (16-bit) and long (32-bit) numbers. sendto(2) - send a datagram to a port somewhere on the internet. s is your socket, msg is the message to send (you can send null-length messages), flags can be left as the default (0) and tolen is the length of the sockaddr structure. Note that you can also use connect(2) and then one or more send(2) calls to accomplish the same thing. recvfrom(2) - receive a datagram from a port. Same as above, except that the fromlen is passed by reference now (ie. as a pointer) rather than by value. This means that it needs to be in a variable - you can't simply put in a pointer to the sizeof() function. Simply print out the "buf" that is returned in a printf() call, using an appropriate format string. Think about writing a function that takes an IP address (as a string) and the port number (in host byte order) and returns a socket set up for UDP "connected" to that host/port. You could call such a function "UDPConnect()" Part 2There _could_ be more than one machine on your labs subnet which will reply to these UDP queries. UDP, being connectionless, allows broadcasts. Using a broadcast, discover how many machines are listening on well-known port 3310 and sending back text strings. To use broadcasts, you will need to use the setsockopt(2) call. Set the level to SOL_SOCKET and the optname to SO_BROADCAST. The optval should be a pointer to a variable set to non-zero. Then set the destination IP address to the local broadcast: 192.168.X.255. Alternatively you could try to use the generic broadcast of 255.255.255.255, but this may behave differently - why? Because we don't know how many machines may respond, we don't know how many responses to print. What we need is a timeout after a short while. The correct way to do this is using the select() system call. This is quite complicated, so a simpler idea is to go into an endless loop printing out responses, and then to kill your program manually with Ctrl-C after a second or two. Part 3 - Add your own serverOnce you have completed the first two parts, you can add your own server to the network (again, on our well-known port). Make sure it abides by the rules including only sending up to 99 bytes of message back otherwise you will be interfering with your classmates doing part 2! | |||||||||||||||||||||||||||||||||||||||||||
|
Please direct all enquiries to: bob@cs.anu.edu.au Page authorised by: Head of School, SoCS |
| The Australian National University — CRICOS Provider Number 00120C |