You are on page 1of 71

Network Programming Laboratory Manual

Department of Electrical Engineering COMSATS Institute of Information Technology, Lahore

Compiled by Muhammad Farooq-i-Azam Assistant Professor Department of Electrical Engineering

Acknowledgements
Mr. Ahmad Mudassir Ms. Tabassum Nawaz Bajwa

Student Evaluation Sheet

Name of student: ---------------------------# 1 2 3 4 5 6 7 8 9 Experiments


Introduction to Linux Operating System Exploring the Linux Command Line Interface Writing, Compiling and Executing C programs Pointers and Structures

Registration Number: ----------------Debugging 4 marks Output 2 marks Total marks Date Signature

Execution 4 marks

System Calls

Introduction to Sockets

TCP Client

TCP Server

Domain Name Resolution

10 UDP Client 11 UDP Server 12 I/O Multiplexing

List of Exercises
Lab-1: Introduction to Linux Operating System Lab-2: Exploring the Linux Command Line Interface Lab-3: Writing, Compiling and Executing C programs Lab-4: Pointers and Structures Lab-5: System Calls Lab-6: Introduction to Sockets
Lab-7: TCP Client Lab-8: TCP Server Lab-9: Domain Name Resolution Lab-10: UDP Client Lab-11: UDP Server Lab-12: I/O Multiplexing

Laboratory Exercise No. 1 Introduction to Linux Operating System


1.1 Objective Introduction to Linux Working with Linux Linux Graphical Environment Linux Command Line Environment

1.2 What is Linux Linux is a true 32-bit operating system that runs on a variety of different platforms, including Intel, Sparc, Alpha, and Power-PC (on some of these platforms, such as Alpha, Linux is actually 64-bit). Linux was first developed back in the early 1990s, by a young Finnish thenuniversity student named Linus Torvalds. Linus had a "state-of-the-art" 386 box at home and decided to write an alternative to the 286-based Minix system (a small unix-like implementation primarily used in operating systems classes), to take advantage of the extra instruction set available on the thennew chip, and began to write a small bare-bones kernel. The interesting thing about Linux is, it is completely free! Linus decided to adopt the GNU Copyleft license of the Free Software Foundation, which means that the code is protected by a copyright -- but protected in that it must always be available to others. Free means free -- you can get it for free, use it for free, and you are even free to sell it for a profit (this isn't as strange as it sounds; several organizations, including Red Hat, have packaged up the standard Linux kernel, a collection of GNU utilities, and put their own "flavour" of included applications, and sell them as distributions. Some common and popular distributions are Slackware, Red Hat, SuSe, and Debian)! The great thing is, you have access to source code which means you can customize the operating systems to your own needs, not those of the "target market" of most commercial vendors. Linux can and should be considered a full-blown implementation of unix. However, it can not be called "Unix"; not because of incompatibilities or lack of functionality, but because the word "Unix" is a registered trademark owned by AT&T, and the use of the word is only allowable by license agreement.

1.3 Linux User Interface Linux provides both graphical and command line interfaces. Here are some points comparing GUI and CLI. GUI makes it easy for the user, therefore makes the OS user-friendly. GUI interface means the OS is "dumbed down" CLI gives the user more control and options. CLI is stone-aged; it belongs to a "The History of Computers" museum. Xwindows is progress compared to the CLI. Xwindows presents a really big security risk...load it and you are asking to be hacked. Using GUI is faster. Picking and choosing icons sure beats trying to remember and typing command lines. Using CLI is faster. A keyboard is pretty much all you need here, much faster than all that clicking, scrolling, clicking some more, scrolling some more, and more typing, then clicking. GUI consumes too much CPU and memory. With newer and more powerful computers, that is not a problem. And its benefits are well worth it. CLI and GUI are essentially complementary modes of interacting with the computer. CLI is generally easier if you can remember the commands and the options, which is the case if you use them a lot. If you don't use certain functions a lot, a nice GUI can help you find them quickly. Of course whenever you have to repeat a command many times you should automate the process by writing a script, but in theory you could link that script to a button or menu item in a GUI. It doesn't have to stay at the command line.

Development and programming are mostly done using command line interface. Therefore, our focus during this course would be to use the command line options. Task 1: Power on the computer system and boot into Linux. (a) Describe the name of boot loader used by your computer system.

(b) Describe the choices offered by the boot loader.

(c) What is the default operating system booted by the boot loader?

(d) Does your Linux operating system boot into the graphical interface or the command line interface.

(e) What is the name and version of Linux distribution used by your computer system?

1.3.1 Logging in Linux Many of the computer systems in the laboratory are dual-boot i.e. they can boot both Windows and Linux. As the system boots, the boot loader will ask you for the choice of the operating system. Please highlight Linux and press Enter. As you boot into Linux, it may boot into the graphical environment or the command line environment. In any case, you have to provide your login name (i.e. user name) and password. Please obtain your login credentials from the laboratory staff.

1.3.2 Switching from GUI to Command Line If you are in the graphical environment and would like to switch to command line, press CTRL + ALT + F2 You will get a login screen in the command line environment. This is also called virtual console.

Enter you login name and password. After you press enter, you will get shell prompt: $ At this shell prompt you can enter Linux commands. You can open more than one virtual console at the same time. After you have logged into virtual console by pressing CTRL + ALT + F2, please press CTRL + ALT + F3 You will get another login screen of another virtual console. You can again login here with the same login name as in the previous console or even with a different login name. Similarly you can open still further virtual consoles, by pressing CTRL + ALT + F4 CTRL + ALT + F5 CTRL + ALT + F6 and so on. After you have logged into two ore more virtual consoles, you can switch back and forth amongst any of them by pressing the desired CTRL + ALT + Fn key combinations. Task 2: Login into at least four virtual consoles by pressing CTRL + ALT + Fn. Choose n of your liking between 2 and 6. (a) Write down below how you switched from one virtual console to the other.

(b) Write down the exact messages and login prompt printed by the command line login screen. Does it include version of the Linux kernel or the particular Linux distribution.

(c) Write down messages printed by the virtual console after you log in.

(d) Switch back and forth between all the virtual consoles you have opened. Describe, whether you have to re-login every time you come back to a virtual console? 1.3.3 Switching from Command Line to GUI You have to press CTRL + ALT + F1 or CTRL + ALT + F7 depending upon the particular Linux distribution and its version you are using. Task 3: (a) Determine and describe whether GUI of your operating system is located at CTRL + ALT +F1 or CTRL + ALT + F7.

(b) Login into the graphical interface by providing your login name and password. Describe which takes more time to login: command line or graphical?

(c) Describe the layout of the desktop screen? Compare it to the Microsoft Windows desktop screen that you have earlier used?

Task 4: (a) Please explore all the menus offered by your graphical desktop and describe what sort of functions is provided by the graphical interface. Compare and contrast them with the features offered by Microsoft Windows.

(b) Find and use the web browser to browse the web. Do you feel any differences as compared to Microsoft Windows environment?

(c) Find and use document publishing software i.e. like those of Microsoft Word and Excel. Produce one test.doc document which is compatible to the format offered by Microsoft Word and one test.xls which is compatible to the format offered by Microsoft Excel.

10

Laboratory Exercise No. 2 Exploring the Linux Command Line Interface


2.1 Objectives Using the command line interface Frequently Used Commands Exploring Linux File System

2.2 Linux Command Line Interface When you login to a command line interface, you get a shell prompt like below: $ At this shell prompt you can enter Linux commands. There are plenty of Linux commands that you can use at this shell prompt. Because, Linux shell prompt looks much like MS DOS prompt, some people think that Linux command line is much like MS DOS command line. However, in reality, there is vast difference in terms of capability of both environments. Linux command line is so much powerful as compared to MS DOS. Here are some of the basic Linux commands that you can use at the shell prompt. For more detailed information about commands consult the handout provided by the teacher. 2.2.1 Linux Command ls $ ls This gives you list of files and directories in your current working directory. There may be no files visible in your home directory, in which case, the UNIX prompt will be returned. Alternatively, there may already be some files inserted by the System Administrator when your account was created. ls does not, in fact, cause all the files in your home directory to be listed, but only those ones whose name does not begin with a dot (.) Files beginning with a dot (.) are known as hidden files and usually contain important program configuration information. They are hidden because you should not change them unless you are very familiar with UNIX!!!

11

To list all files in your home directory including those whose names begin with a dot, type $ ls -a ls is an example of a command which can take options: -a is an example of an option. The options change the behaviour of the command. There are online manual pages that will tell you which options a particular command can take, and how each option modifies the behaviour of the command. Similarly another option l provides a more detailed listing of the files in your directory. $ ls -l You can combine options too, like the following: $ ls -l -a or like the following: $ ls -la mkdir To create directories you can use mkdir command. For example, if you have to create a directory named testdir, use the following command: $ mkdir testdir To see the directory, you have just created, use $ ls cd The command cd directory means change the current working directory to 'directory'. The current working directory may be thought of as the directory you are in, i.e. your current position in the file-system tree. To change to the directory you have just made, type $ cd testdir Type ls to see the contents of testdir.

12

pwd Pathnames enable you to work out where you are in relation to the whole filesystem. For example, to find out the absolute pathname of your homedirectory, type cd to get back to your home-directory and then type $ pwd The full pathname will look something like this /home/datacom which means that datacom (your home directory) is in the directory /home. To go to the parent directory /home you can use $ cd ..

Task 1: (a) Login into a new virtual console. At the login prompt, use $ pwd This gives path to your home directory. Write down the name of your home directory with full pathname.

(b) Use ls command to see the list of files in your home directory. Also use $ ls -l to see list of files with details. Please describe all the columns of the output you get in the detailed list.

13

Task 2: Use $ ls -l Read about various output columns and describe what kind of information is provided by each column. Also describe permissions of at least one file in the output.

Task 3: (a) Create the following directories in your home directory. test1/test2 test1/test3 Use mkdir and cd commands to accomplish the above tasks. Please write the sequence of commands you will use to create the above directory tree starting from your home directory.

14

(b) Create the following directory trees after you have created the above directory tree. /test1/test2/test22 /test1/test3/test32 Please write the sequence of commands you will use to create the above directory tree starting from your home directory.

Task 4: Go to the following empty directory you have created: /home/datacom/test1/test2/test22 Get a detailed list of the files in the empty directory using $ ls -la Please describe the output of the above command. Which files and directories are included in the output list. Please write a note on the directories included in the above output list.

15

Task 5: A useful command which provides help on the commands is man which is short for manual. Use $ man ls to learn more about ls command. Please write down below what additional things you have learnt. Use man command to learn more about the commands and their options you have learnt to use till now. Please describe additional knowledge you have got.

Task 6: To get help about the man command itself, you can use $ man man Please use the above command line to learn more about the man command. Please describe: (a) (b) (c) How many sections are there in the manual pages In which section are the user commands listed. In which section are the Linux system calls listed.

16

Task 7: Go to the directory / which is called root directory using $ cd / Then take a list of the files in the / directory using: $ ls -l Please list the entire directory present you get. This is typical directory structure of a Linux filesystem. Please learn more about what each of these directories contains either using your Linux notes or from the Internet and describe the usage of each of these directories.

17

Task 8: Use man command to learn more about the following Linux commands: cp, mv, rm, rmdir, clear, cat, less, head, tail, grep, who, whoami Then use these commands to accomplish various test tasks. Please describe what each of these commands does by giving at least one example of each of these commands.

18

Laboratory Exercise No. 3 Writing, Compiling and Executing C programs


3.1 Objectives What are the steps involved. Writing a C program Compiling a C program source code Executing a program 3.2 What are the Steps Involved Here are the three steps you have to go through from writing to executing a program: (a) You have to write a source code file. You use a text editor to write a program. (b) After you have written source code for the program, you have to compile and link it using a compiler and linker. This gives you executable file. (c) You can run the executable file a.out using $ ./a.out 3.3 Writing a C Program To write a program, you first use a text editor to create a source code file. There are multiple text editors available. We will be using nano text editor. Task 1: Create a text file test.txt using the nano editor with random text in it. To create text file, you may use: $ nano test.txt After you open the editor, help is available at the bottom of the screen. Please describe the key combinations you use to perform at least four tasks: Save a text file Read in a previously stored text file Go to previous page Exit from the editor

19

Task 2: Open nano and save the following program as hello.c. #include <stdio.h> int main ( ) { printf ( Hello!\n ); return 0; }

3.4 Compiling a C Program source code To compile and link the source file created, you need to compile and link it. Both functions are normally included in a single program. We can use either cc or gcc in Linux for this purpose. Task 3: To compile the source file created in the previous task, use the following: $ gcc hello.c Use ls to see the output file created. By default Linux creates a.out. To change the output file created, you can use o option with gcc as following: $ gcc -o hello hello.c The output executable file created now will be hello. Please repeat all the above steps on your terminal and write any observations below. If you find any warnings or errors in your program, please also describe them here and explain what information is provided by these warning and error messages.

20

3.5 Executing a program After the program is compiled the program has to execute through exec file. The programs execution is done through highlighted command given below. Task 4: Execute the output executable file hello.c created above using the following: $ ./hello Please give your observations.

Modify the hello.c program by removing \n in the printf statement and save it as hello1.c Recompile and create an executable file hello1.c. Execute this program. Note any differences as compared to hello.c.

21

Laboratory Exercise No. 4 Pointers and Structures


4.1 Objectives Understanding Pointers Understanding Structures Pointers to Structures 4.2 Understanding Pointers Pointers form the core of programming in C language. A pointer is a very powerful mechanism through which a program can access a memory location directly. A pointer is simply an address to a memory location. In other words, a pointer is a variable that contains the memory location of another variable. The syntax is as shown below. You start by specifying the type of data stored in the location identified by the pointer. The asterisk tells the compiler that you are creating a pointer variable. Finally you give the name of the variable. type * variable name Example: int *ptr; float *string; Once we declare a pointer variable we must point it to something we can do this by assigning to the pointer the address of the variable you want to point as in the following example: ptr=&num; This places the address where num is stores into the variable ptr. If num is stored in memory 21260 address then the variable ptr has the value 21260. Task 1: Write and compile the program below: int main() { int *ptr; int sum; sum = 45; ptr = &sum; printf (Sum is %d\n, sum);

22

printf (*ptr = %d\n, *ptr ); printf (ptr = %p, ptr); return 0; } What is the output of this program. Please describe.

Like other variables pointer variables can be used in expressions. For example if p1 and p2 are properly declared and initialized pointers, then the following statements are valid. y=*p1**p2; sum=sum+*p1; *p2= *p2 + 10; C allows us to add integers to or subtract integers from pointers as well as to subtract one pointer from the other. We can also use short hand operators with the pointers e.g. sum+=*p2; etc. we can also compare pointers by using relational operators the expressions such as p1 >p2 , p1==p2 and p1!=p2 are allowed. Task 2: Write, compile and execute the program below: #include< stdio.h > int main() { int ptr1, ptr2; int a,b,x,y,z; a=30;b=6; ptr1=&a; ptr2=&b; x=*ptr1+ *ptr2 6; printf(Address of a +%u\n, ptr1); printf(Address of b %u\n, ptr2); printf(a=%d, b=%d\n, a, b); printf(x=%d\n, ,x);

23

ptr1=ptr1 + 70; ptr2= ptr2; printf(a=%d, b=%d, a, b); return 0; } What are the final values of variables a and b? How do you explain these final values? Please elaborate.

4.3 Understanding Structures W can declare the form of a block of data containing different data types by means of a structure declaration. For example, a personnel file might contain structures which look something like: struct tag { char lname[20]; char fname[20]; int age; float rate; };

/* last name */ /* first name */ /* age */ /* e.g. 12.75 per hour */

Later, we can declare a variable of type struct tag as below: struct tag myVariable; Task 3: Here is a program that uses structure to store information of an employee and then displays this information. #include <stdio.h> #include <string.h>

24

int main(void) { struct tag { char lname[20]; char fname[20]; int age; float rate; };

/* last name */ /* first name */ /* age */ /* e.g. 12.75 per hour */ /* declare the structure my_struct */

struct tag my_struct;

strcpy(my_struct.lname,"Muhammad"); strcpy(my_struct.fname,"Yasir"); my_strcut.age = 20; my_struct.rate = 5000; printf ("%s ", my_struct.fname); printf ("%s", my_struct.lname); printf (Age = %d\n, my_struct.age ); printf (Rate = %.2f\n, my_struct.rate ); return 0; }

Write, compile and execute this program and explain the output.

This particular structure that we have used in above program is rather small compared to many used in C programs. To the above we might want to add: date_of_hire; (data types not shown) date_of_last_raise; last_percent_increase; emergency_phone; medical_plan; etc.....

25

4.4 Pointers to Structures If we have a large number of employees, what we want to do is manipulate the data in these structures by means of functions. For example we might want a function print out the name of the employee listed in any structure passed to it. However, in the original C (Kernighan & Ritchie, 1st Edition) it was not possible to pass a structure, only a pointer to a structure could be passed. In ANSI C, it is now permissible to pass the complete structure. If we pass the whole structure it means that we must copy the contents of the structure from the calling function to the called function. In systems using stacks, this is done by pushing the contents of the structure on the stack. With large structures this could prove to be a problem. However, passing a pointer uses a minimum amount of stack space. Consider the case described, i.e. we want a function that will accept as a parameter a pointer to a structure and from within that function we want to access members of the structure. For example we want to print out the name of the employee in our example structure. Our pointer is going to point to a structure declared using struct tag. We declare such a pointer with the declaration:

struct tag *st_ptr; and we point it to our example structure with: ptr = &my_struct; Now, we can access a given member by de-referencing the pointer. Consider the fact that we might want to use the pointer to set the age of the employee. We would write: (*ptr).age = 63; It says, replace that within the parenthesis with that which ptr points to, which is the structure my_struct. Thus, this breaks down to the same as my_struct.age. However, this is a fairly often used expression and the designers of C have created an alternate syntax with the same meaning which is: ptr->age = 63; In other words, give a pointer to a structure variable, we can access the member of the structure variable using -> operator.

26

Task 4: Write, compile and execute the following program. #include <stdio.h> #include <string.h> int main(void) { struct tag{ char lname[20]; char fname[20]; int age; float rate; }; /* the structure type */ /* last name */ /* first name */ /* age */ /* e.g. 12.75 per hour */

struct tag my_struct; /* define the structure */ void show_name(struct tag *p); /* function prototype */

struct tag *st_ptr; /* a pointer to a structure */ st_ptr = &my_struct; /* point the pointer to my_struct */ strcpy(my_struct.lname,"Muhammad"); strcpy(my_struct.fname,"Yasir"); printf("%s ", my_struct.fname); printf("%s", my_struct.lname); my_struct.age = 63; show_name(st_ptr); /* pass the pointer */ return 0; } void show_name(struct tag *p) { printf("%s ", p->fname); /* p points to a structure */ printf("%s ", p->lname); printf("%d", p->age); }

What does this program print? Explain the output.

27

Laboratory Exercise No. 5 System Calls


5.1 Objectives What is a System Call? System Calls vs. Library Calls Examples 5.2 What is a System Call? A system call is a request made by any program to the operating system for performing tasks. In other workds, system calls provide the interface between a process and the operating system. Most operations interacting with the system require permissions not available to a user level process, e.g. I/O performed with a device present on the system or any form of communication with other processes requires the use of system calls. In general, a "system call" is the API through which a program can request OS level services such as read/write/open/close devices (disk, comm, etc.) utilizing the "kernel mode" processing. This is typically the "way in" to the device driver itself from an application. The basic difference is that when a system call is used, this will generate a "context switch" (interrupt) which can be expensive in terms of execution time (in real time systems). System calls are provided by the system and are executed in the system kernel. They are entry points into the kernel and are therefore NOT linked into your program. These are not portable calls. 5.3 System Calls vs. Library Calls Library calls include the ANSI C standard library and are therefore portable. These functions are linked into your program. It is worth noting that, because system calls are part of the O/S, the program has to make a context switch to the kernel when they are called and because of this, they have a high startup overhead. The upside is that the time executing these routines is assigned to the OS and not the user program.

A library function can be built upon and around system calls to allow for the perception of varied access to devices. It can also use no system level service at all.

In general, library functions execute predominantly in user space unless they invoke a system level service request (system call).

28

5.4 Examples C standard library functions exist for various tasks e.g. handling files, I/O devices, string handling, etc. Likewise, there are system calls available to perform various tasks. We will be using file handling as an example to demonstrate the difference between C standard library calls and system calls. For example, prototypes of some of the C standard library functions to handle files are given below: #include <stdio.h> FILE * fopen(const char *filename, const char *mode); size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream); int fclose(FILE *stream); Please note that above library functions are portable. The corresponding system calls for a Linux operating system are given below: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags, mode_t mode); #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); #include <unistd.h> int close(int fildes); Please note that above system calls are for Linux operating system only and are not portable. Another operating system like Microsoft Windows would have its own specific system calls for the tasks performed by the above system calls. Task 1: Linux provides any easy way to see help on any of the standard library calls or system calls using man or info pages.

29

Use the following command to see help on the fopen() library function and open() system call. Please desribe various arguments passed to both these calls and values returned by them. Also compare and contrast the difference and level of control provided to the program by these calls. $ man 3 fopen $ man 2 open You might have noted that C standard library functions are described in section 3 of the manual pages and the system calls are described in the section 2 of the manual pages.

30

Task 2: Please read man pages of all the library functions and system calls described in section 4.2 above. Describe the arguments to each of these functions and calls. Also compare and contrast the corresponding library functions and calls.

31

Task 3: Write, compile and execute the following program:

#include <stdio.h> #include <stdlib.h> int main ( void ) { FILE * fptr; char name[] = "Muhammad Ali.\n"; char id[] = "BTE-SP09-200\n"; size_t n; fptr = fopen ( "file.txt", "w" ); if (fptr == NULL) { perror ( "fopen" ); exit ( EXIT_FAILURE ); } n = fwrite ( name, sizeof (name), 1, fptr); if ( n == 0 ) { perror ( "fwrite" ); exit(EXIT_FAILURE); } n = fwrite (id, sizeof(id), 1, fptr); if ( n == 0 ) { perror ( "fwrite" ); exit(EXIT_FAILURE); } if ( fclose (fptr) < 0 ) { perror ( "fclose" ); exit(EXIT_FAILURE); } return 0; }

32

Please explain what this program does?

Does this program use library calls or system calls? Please enlist them.

Please describe any two cases where the above program may fail and calls any of the perror() function calls in the above program.

33

Write a similar program that reads text from the file created by the above program and displays it on the standard output.

34

Task 4: Write, compile and execute the program given below:

#include #include #include #include #include #include

<stdio.h> <stdlib.h> <unistd.h> <sys/types.h> <sys/stat.h> <fcntl.h>

int main ( void ) { int fd; char name[] = "Muhammad Ali.\n"; char id[] = "BTE-SP09-200.\n"; if ( ( fd = open ("file2.txt", O_CREAT | O_WRONLY, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH )) < 0 ) { perror ( "open" ); exit ( EXIT_FAILURE ); } if ( write ( fd, name, sizeof (name) ) < 0 ) { perror ("write"); exit(EXIT_FAILURE); }

if ( write ( fd, id, sizeof (id) ) < 0 ) { perror ("write"); exit(EXIT_FAILURE); } if ( close(fd) < 0 ) { perror("close"); exit(EXIT_FAILURE); } return 0; }

35

Please explain what this program does?

How do you compare this program with the one given in task 3 above. Are there any similarities between these two programs?

Does this program use library calls or system calls? Please enlist them.

36

Laboratory Exercise No. 6 Introduction to Sockets


6.1 Objectives What is a Socket? Types of Sockets Network Communication Using Sockets 6.2 What is a Socket? A socket is an endpoint of a bidirectional inter-process communication between two processes. The processes may be located on the same host or on different hosts located far apart from each other. There are various types of sockets. Of particular interest is the Internet socket or network socket. An Internet socket or network socket is an endpoint of a bidirectional inter-process communication flow across an Internet Protocolbased computer network, such as the Internet. The term Internet sockets is also used as a name for an application programming interface (API) for the TCP/IP protocol stack, usually provided by the operating system. Internet sockets constitute a mechanism for delivering incoming data packets to the appropriate application process or thread, based on a combination of local and remote IP addresses and port numbers. Each socket is mapped by the operational system to a communicating application process or thread. Linux system call used to create a socket is as under: #include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); A socket created by this call can be used for various types of communications including communication over a TCP/IP network or the Internet. The socket() call returns an integer value usually called socket descriptor which is used to refer to the particular socket in later operations on the socket by various system calls. 6.3 Types of Sockets In the socket() system call described above, the variable domain may have different values thus deciding the type of communication performed by the socket.

37

PF_UNIX, PF_LOCAL PF_INET PF_INET6 PF_IPX PF_NETLINK PF_X25 PF_AX25 PF_ATMPVC PF_APPLETALK PF_PACKET

Local communication IPv4 Internet protocols IPv6 Internet protocols IPX - Novell protocols Kernel user interface device ITU-T X.25 / ISO-8208 protocol Amateur radio AX.25 protocol Access to raw ATM PVCs Appletalk ddp(7) Low level packet interface

For communication over TCP/IP network, we use PF_INET, and the socket created with this option is called an Internet socket. The Internet socket can further be classified into two types: 1- TCP Socket This is also called stream socket or connection-oriented socket. In the socket() system call we use SOCK_STREAM value for the type variable. 2- UDP Socket This is also called datagram socket or connectionless socket. In the socket() system call we use SOCK_DGRAM value for the type variable. Task 1: Third option to the socket() system call is an integer value. Please consult socket man page and describe the third argument passed to the socket().

38

6.4 Network Communication Using Sockets If we are to communicate over a TCP/IP network, we need to use AF_INET value for the first option in the socket() system call. However, once the socket has been created using the socket() call, we need some other system calls to use this socket for communication. Some of these calls are listed below: #include <sys/types.h> #include <sys/socket.h> int connect (int socket, const struct sockaddr *address, socklen_t address_len);

This call is normally used for connection-oriented communication to establish connection with the remote host. First argument is the descriptor returned by the socket() call. The second argument is a pointer to a variable of type struct sockaddr. Usually, a structure variable of type struct sockaddr_in is declared and used and then we typecast it to struct sockaddr. Details of the struct sockaddr_in are given below:

#include <netinet/in.h> struct sockaddr_in { short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8]; };

The above structure has another structure variable as member. This structure is defined as below:

struct in_addr { unsigned long s_addr; }; The third argument to the socket() call is the length of variable in the second argument which can be obtained using sizeof operator. connect() returns 0 on success and -1 in case of error.

39

Task 2: Some of the other system calls used in socket() programming include the following: bind(), listen, read(), write() accept, sendto(), recvfrom(),

Consult their man pages and describe their prototypes.

40

Task 3: Write a program that simply opens a socket and then closes it. Also print the value of descriptor returned by the socket() call.

41

Laboratory Exercise No. 7 TCP Client


7.1 Objectives Client-server architecture What is a TCP client? Making a TCP client 7.2 Client-Server Architecture Client-server computing or networking is a distributed application architecture that partitions tasks or work loads between service providers i.e. servers and service requesters, called clients. Often clients and servers operate over a computer network on separate hardware. A server machine is a highperformance host that is running one or more server programs which share its resources with clients. A client does not share any of its resources, but requests a server's content or service function. Clients therefore initiate communication sessions with servers which await (listen to) incoming requests. Client-server describes the relationship between two computer programs in which one program, the client program, makes a service request to another, the server program. Standard networked functions such as email exchange, web access and database access, are based on the client-server model. For example, a web browser is a client program at the user computer that may access information at any web server in the world. 7.3 What is a TCP Client? It is a generic name given to the client application program using TCP protocol at the transport layer. A client application program in a client-server architecture using TCP at the transport layer by means of stream sockets is called a TCP client. For example, a web browser is a TCP client as it uses TCP protocol at the transport layer. The TCP protocol is connection-oriented and adds reliability to the application. Each packet that is sent by the client or server is acknowledged by the other side after it has been received. If the packet is not acknowledged after a particular time, it is re-transmitted. However, this process makes the application a bit slower. 7.4 Making a TCP Client There is almost a standard sequence of calls that are needed to build a TCP client application program. In any TCP client application program, you first create a socket using the

42

socket() system call. After the socket has been created, you request for connection to the remote host by using a connect() system call. After the connection has been made, you either send or receive data or perform both operations upon the socket using write() and read() system calls. After the communication has been made, you close the socket using close() system call. Task 1: Write, compile and execute the following program: #include #include #include #include #include #include <stdio.h> <sys/types.h> <sys/socket.h> <netdb.h> <stdlib.h> <string.h>

int main ( int argc, char * argv[] ) { int clientSocket = 0; int port = 0; int returnStatus = 0; char buffer[256] = ""; struct sockaddr_in serverAddress; if ( argc != 3 ) { fprintf ( stderr, "Usage: %s <server ip> <port>\n", argv[0] ); exit (1); } clientSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( clientSocket < 0 ) { perror ( "socket" ); exit(1); } port = atoi(argv[2]); bzero (&serverAddress, sizeof (serverAddress) );

43

serverAddress.sin_family = AF_INET; inet_addr(argv[1], &serverAddress.sin_addr.s_addr); serverAddress.sin_port = htons(port); returnStatus = connect (clientSocket, (struct sockaddr *)&serverAddress,\ sizeof (serverAddress) ); if (returnStatus != 0) { perror ( "connect" ); close (clientSocket); exit(1); } returnStatus = read(clientSocket, buffer, sizeof(buffer) ); if (returnStatus > 0) printf ( "%d: %s", returnStatus, buffer ); else fprintf (stderr, "Return Status = %d\n", returnStatus); close(clientSocket); return 0; }

Describe what this program does? What happens when you try to run this program in the absence of any server program running?

What command line arguments you have to provide to this program. Explain how you run the program by giving an example of the command line arguments.

44

Task 2: For the program in task 1, write a comment for each line in the program so that all the comments combined fully describe your program.

45

Task 3: We have used the following functions in this program. Please consult their man pages and describe what these functions do? perror(), atoi(), bzero(), htons(), exit()

46

Laboratory Exercise No. 8 TCP Server


8.1 Objectives Server application program What is a TCP server? Making a TCP server 8.2 Server Application Program A server is simply another application program that waits for requests to arrive and then responds to these requests. Server normally does not initiate communication. The communication is initiated by a client application. And the server serves the request made by the client and hence the name server. 8.3 What is a TCP Server A TCP server, as the name indicates, a server application program that uses TCP protocol at the transport layer. It means that the server uses a connectionoriented architecture for communication with the client. For this purpose, it uses stream sockets. Whether to use TCP or UDP at the transport layer is decided by the application layer program. For example, HTTP, SMTP and FTP standards specifiy the use of TCP at the transport layer. Therefore, all these servers implementing these protocols are TCP servers. 8.4 Making a TCP Server Just like the building of a TCP client, there is almost a standard set of calls and sequence to develop a TCP server. In the first place, you need to open a socket using the socket() call. This socket will always be open as long as the server program is running and will be used to listen for connection requests. After the socket has been created, you need to bind it to the local IP addresses of the host on which the server application is running using the bind() call. Next, you specify the length of queue to hold the requests for simultaneous connections using listen() call. If a request is being processed and new request arrives, it is held in the queue and will be processed only after the current request has been served. In other words, the requests are processed in a serial fashion. For this reason, this type of server which we are going to develop here is called a serial server. Once, we have set up queue, we are ready to accept connection requests from clients. This is done using the accept() system call. After processing on

47

request, the server must wait for next request. Therefore, this connection requests are handled within a loop. The accept() returns a child socket for communication with the client. The main server socket is thus free to listen to next connection requests. Next, we send or receive data to or from the client using the child socket. For this purpose, we use read() and write() system calls though other options are also available. After we have finished communication with the client, we close the child socket using close() system call. Task 1: Write, compile and execute the following program: #include #include #include #include #include #include <stdio.h> <sys/types.h> <sys/socket.h> <netdb.h> <stdlib.h> <string.h>

int main ( int argc, char * argv[] ) { const char MESSAGE[] = "In the name of Allah,the Most Merciful and the Most\ Beneficient.\n"; int serverSocket = 0; int port = 0; int returnStatus = 0; struct sockaddr_in serverAddress; if ( argc != 2) { fprintf ( stderr, "Usage: %s <port>\n", argv[0] ); exit ( 1 ); } serverSocket = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( serverSocket < 0 ) { perror ( "socket" ); exit ( 1 ); }

48

port = atoi ( argv[1] ); bzero ( &serverAddress, sizeof (serverAddress) ); serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr =htonl(INADDR_ANY); serverAddress.sin_port = htons ( port ); returnStatus = bind ( serverSocket, (struct sockaddr *)&serverAddress, \ sizeof (serverAddress) ); if ( returnStatus != 0 ) { perror ( "bind" ); close ( serverSocket ); exit ( 1 ); } returnStatus = listen ( serverSocket, 5 ); if ( returnStatus < 0 ) { perror ( "listen" ); close ( serverSocket ); exit ( 1 ); } while ( 1 ) { struct sockaddr_in clientAddress = { 0 }; int childSocket = 0; int clientAddressLength = sizeof(clientAddress); childSocket = accept ( serverSocket, (struct sockaddr *)&clientAddress, \ &clientAddressLength ); if ( childSocket < 0 ) { perror ( "accept" ); close ( "serverSocket" ); exit ( 1 ); } write (childSocket, MESSAGE, strlen(MESSAGE)); close ( childSocket ); } close ( serverSocket ); return 0; }

49

Task2: Describe what does program described in Task 1 do? Run this program in one virtual window on your linux machine. Then open another virtual window and run the client program given in the previous lab no. 7 in the new virtual window. Note down the results and the reasons of these result you get. As an example, you can use the following command lines to run the programs: $ ./serverprogram 777

Run the client application program on the same computer but in another virtual window: $ ./clientprogram 127.0.0.1 777

Task 3: What happens if multiple clients simultaneously try to establish connection with the server? How many simultaneous connection requests can this server program handle?

Task 4: Run the server program given in this exercise on one computer and the client application program given in the previous exercise no. 7 on another computer. You must sepcify the IP address of the server machine to client program on the command line. To find the IP address of the server machine, use the following command on the computer running the server program: $ /sbin/ifconfig Describe the results you achieved after running both the programs.

50

Task 5: For the program in task 1, write a comment for each line in the program so that all the comments combined fully describe your program.

51

Laboratory Exercise No. 9 Domain Name Resolution


9.1 Objectives Domain Name Service Name Resolution Getting Host Information 9.2 Domain Name Service When you use the web or send an e-mail message, you use a domain name to do it. For example, the URL http://www.ciitlahore.edu.pk contains the domain name ciitlahore.edu.pk. So does the e-mail address email@ciitlahore.edu.pk. Machines and computers use IP addresses to send and receive packets and exchange information. However, it is difficult for humans to remember the IP addresses. Therefore, machines are assigned names that humans can remember easily. For example, the machine that humans refer to as www.ciitlahore.edu.pk has the IP address 174.37.202.106. Whenever, humans refer to a domain name, the machines translate them to the corresponding IP address using a service called Domain Name Service. 9.3 Name Resolution The Domain Name System i.e. DNS is a hierarchical naming system for computers, services, or any resource participating in the Internet. It translates humanly meaningful domain names to the numerical identifiers (i.e. IP addresses) associated with networking equipment for the purpose of locating and addressing these devices world-wide. The domain name space consists of a tree of domain names. Only one node or leaf in the tree has zero or more resource records, which hold information associated with the domain name. The tree sub-divides into zones beginning at the root zone. A DNS zone consists of a collection of connected nodes authoritatively served by an authoritative nameserver. Note that a single nameserver can host several zones. Administrative responsibility over any zone may be divided, thereby creating additional zones. Authority is said to be delegated for a portion of the old space, usually in form of sub-domains, to another nameserver and administrative entity. The old zone ceases to be authoritative for the new zone. 9.4 Getting Host Information Given a host name, you can retrieve addressing information of the host by the following system call:

52

#include <netdb.h> struct hostent * gethostbyname(const char *name); struct hostent is defined as below: struct char char int int char }; hostent { *h_name; **h_aliases; h_addrtype; h_length; **h_addr_list;

/* /* /* /* /*

official name of host */ alias list */ host address type */ length of address */ list of addresses from name server */

Similarly, if you have IP address and would like to find the host name, you can use the following system call: #include <netdb.h> #include <sys/socket.h>

/* for AF_INET */

struct hostent * gethostbyaddr(const void *addr, int len, int type); Task 1: Write, compile and execute the following program: #include #include #include #include #include #include <netinet/in.h> <arpa/inet.h> <unistd.h> <netdb.h> <stdio.h> <stdlib.h>

int main ( int argc, char * argv[] ) { char * host, **names, **addrs; struct hostent *hostinfo; if ( argc == 1 ) { char myname[256]; gethostname( myname, 255 ); host = myname; } else host = argv[1]; hostinfo = gethostbyname( host );

53

if ( !hostinfo ) { perror ( "gethostbyname" ); exit (EXIT_FAILURE); } printf ( "Results for host %s:\n", host ); printf ( "Name: %s\n", hostinfo->h_name ); printf ( "Aliases: " ); names = hostinfo->h_aliases; while ( *names ) { printf ( " %s", *names ); names++; } printf ( "\n" ); if ( hostinfo->h_addrtype != AF_INET ) { fprintf ( stderr, "Not an IP host.\n" ); exit ( EXIT_FAILURE ); } addrs = hostinfo->h_addr_list; while(*addrs) { printf ( " %s", inet_ntoa( *(struct in_addr *) *addrs )); addrs++; } printf ( "\n" ); exit ( EXIT_SUCCESS ); }

Descibe the output of the above program and explain it in your own words.

54

Task 2: Run the above program by passing it a hostname on the command line. For example: $ ./progname yahoo.com What is the result of running this program? Please describe how your program obtained these results. Note that you must be connected to the Internet for above program to be able to produce results.

Task 3: Write a program similar to above but it should get the hostname given an IP address. Run the program and describe the results. Note that you can use gethostbyaddr() for this purpose.

55

Laboratory Exercise No. 10 UDP Client


10.1 Objectives UDP Protocol What is a UDP client? Making a UDP client 10.2 UDP Protocol The User Datagram Protocol (UDP) is one of the core members of the Internet Protocol Suite. UDP uses a simple transmission model without implicit handshaking dialogues for guaranteeing reliability, ordering, or data integrity. Thus, UDP provides an unreliable service and datagrams may arrive out of order, appear duplicated, or go missing without notice. UDP assumes that error checking and correction is either not necessary or performed in the application, avoiding the overhead of such processing at the network interface level. Time-sensitive applications often use UDP because dropping packets is preferable to waiting for delayed packets, which may not be an option in a real-time system. Common network applications that use UDP include: the Domain Name System (DNS), streaming media applications such as IPTV, Voice over IP (VoIP), Trivial File Transfer Protocol (TFTP) and many online games. 10.3 What is a UDP Client? It is a generic name given to the client application program using UDP protocol at the transport layer. A client application program in a client-server architecture using UDP at the transport layer by means of datagram sockets is called a UDP client. Most of the voice and streaming video applications use UDP at the transport layer. The UDP protocol is connectionless and guarantees no reliability to the application. No acknowledgement is provided for any received packet. There is no packet sequencing or re-transmission either. 10.4 Making a UDP Client Like the making of a TCP client application, there is almost a standard sequence of calls that are needed to build a UDP client application program. However, unlike UDP, you are not required to use connect() system call as the UDP protocol is not connection-oriented. You first create a socket using the socket() system call using SOCK_DGRAM as socket type. After the socket has been created, you can start sending and receiving data through the socket using sendto() and

56

recevfrom() calls. After the communication ends, you close the socket using close() system call. Task 1: Consult man pages and write prototypes of both read() and recvfrom() system calls below.

Task 2: Consult man pages and write prototypes of both write() and sendto() system calls below.

Task 3: Consult man page of connect() system call and describe whether you can use it with UDP sockets at all? If so, under what circumstances?

57

Task 4: Following program is a UDP client application program. It just sends a string to a UDP server and then receives back a string from the server and displays it on standard output. Write, compile and execute this program.

#include #include #include #include #include #include

<sys/types.h> <sys/socket.h> <netdb.h> <string.h> <stdio.h> <stdlib.h>

#define MAXBUF 1024 int main ( int argc, char * argv[] ) { int udpSocket; int returnStatus; int addrlen; struct sockaddr_in udpClient, udpServer; char buf[MAXBUF]; if ( argc < 3 ) { fprintf ( stderr, "Usage: %s <ip address> <port>\n", argv[0] ); exit ( 1 ); } udpClient.sin_family = AF_INET; udpClient.sin_addr.s_addr = INADDR_ANY; udpClient.sin_port = 0; udpServer.sin_family = AF_INET; udpServer.sin_addr.s_addr = inet_addr(argv[1]); udpServer.sin_port = htons(atoi(argv[2])); udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if ( udpSocket < 0 ) { perror ( "socket" ); exit ( EXIT_FAILURE ); } strcpy ( buf, "In the name of Allah, the Most Merciful and\ the Most Beneficient.\n" ); returnStatus = sendto ( udpSocket, buf, strlen(buf)+1, 0, (struct sockaddr *)&udpServer, sizeof(udpServer) ); if ( returnStatus < 0 ) { perror ( "sendto" ); exit ( EXIT_FAILURE ); }

58

printf ( "Message Sent.\n" ); addrlen = sizeof ( udpServer ); returnStatus = recvfrom ( udpSocket, buf, MAXBUF, 0, (struct sockaddr *)&udpServer, &addrlen ); if ( returnStatus < 0 ) { perror ( "recvfrom" ); exit ( EXIT_FAILURE ); } else { buf[returnStatus] = 0; printf ( "Received: %s\n", buf ); } if ( close ( udpSocket ) < 0 ) { perror ( "close" ); exit ( EXIT_FAILURE ); } return 0; }

What happens when you try to run this program in the absence of any server program running?

What command line arguments you have to provide to this program. Explain how you run the program by giving an example of the command line arguments.

59

Task 5: For the program in task 4, write a comment for each line in the program so that all the comments combined fully describe your program.

60

Laboratory Exercise No. 11 UDP Server


11.1 Objectives What is a UDP server? Making a UDP server 11.2 What is a UDP Server? A UDP server, as the name indicates, a server application program that uses UDP protocol at the transport layer. It means that the server uses a connectionless architecture for communication with the client. For this purpose, it uses datagram sockets. Whether to use TCP or UDP at the transport layer is decided by the application layer program. Note that only those client application programs that use UDP protocol will be able to communicate with a UDP server program. Similarly, only TCP client applcation programs will be able to communicate with TCP server application programs. 11.3 Making a UDP Server First of all, you open a socket using the socket() call and using SOCK_DGRAM for the socket type. After the socket has been created, you need to bind it to the local IP addresses of the host on which the server application is running using the bind() call. After the socket has been created and bound, you can start sending and receiving data using sento() and recvfrom() system calls. After we have finished communication with the client, we close the socket using close() system call. Task 1: What do you think, why dont we use accept() system call with UDP sockets? Please explain.

61

Task 2: Following is a UDP server application program that receives a string from a UDP client program and sends back a string OK to the client. Write, compile and execute the program.
#include #include #include #include #include #include <sys/types.h> <sys/socket.h> <netdb.h> <string.h> <stdio.h> <stdlib.h>

#define MAXBUF 1024 int main ( int argc, char * argv[] ) { int udpSocket; int returnStatus = 0; int addrlen = 0; struct sockaddr_in udpServer, udpClient; char buf[MAXBUF]; if ( argc < 2 ) { fprintf (stderr, "Usage: %s <port>\n", argv[0] ); exit(1); } udpServer.sin_family = AF_INET; udpServer.sin_addr.s_addr = htonl(INADDR_ANY); udpServer.sin_port = htons (atoi(argv[1])); udpSocket = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); if ( udpSocket < 1 ) { perror ( "socket" ); exit ( EXIT_FAILURE ); } returnStatus = bind ( udpSocket, ( struct sockaddr *)&udpServer, sizeof(udpServer) ); if ( returnStatus != 0 ) { perror ( "bind" ); exit (EXIT_FAILURE); } while(1) { addrlen = sizeof (udpClient); returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr * )&udpClient, &addrlen ); if ( returnStatus < 0 ) {

62

perror ( "recvfrom" ); exit (EXIT_FAILURE); } printf ( "Received: %s\n", buf ); strcpy ( buf, "OK" ); returnStatus = sendto ( udpSocket, buf, strlen(buf) + 1, 0, (struct sockaddr *)&udpClient, sizeof(udpClient) ); if ( returnStatus < 0 ) { perror ( "sendto" ); exit ( EXIT_FAILURE ); } } if ( close ( udpSocket ) < 0 ) { perror ( "close" ); exit ( EXIT_FAILURE ); } return 0; }

Describe the results of running the above program below:

63

Task2: Run the program above in one virtual window on your linux machine. Then open another virtual window and run the client program given in the previous lab no. 10 in the new virtual window. Note down the results and the reasons of these result you get. As an example, you can use the following command lines to run the programs: $ ./serverprogram 777

Run the client application program on the same computer but in another virtual window: $ ./clientprogram 127.0.0.1 777

Task 3: What happens if multiple clients simultaneously try to establish connection with the server? How many simultaneous connection requests can this server program handle?

Task 4: Run the server program given in this exercise on one computer and the client application program given in the previous exercise no. 7 on another computer. You must sepcify the IP address of the server machine to client program on the command line. To find the IP address of the server machine, use the following command on the computer running the server program: $ /sbin/ifconfig Describe the results you achieved after running both the programs.

64

Task 5: For the program in task 1, write a comment for each line in the program so that all the comments combined fully describe your program.

65

Laboratory Exercise No. 12 I/O Multiplexing


12.1 Objectives Need for Multiplexing Implementing Multiplexing 12.2 Need for Multiplexing Servers developed above handle only one client at one time. In real life, servers normally have to cater to requests from multiple clients simultaneously. Handling multiple clients at the same time requires solving several problems. The first issue is allowing multiple clients to connect and stay connected simultaneously. Multiplexing is one of the strategies to handle this issue. After implementing multiplexing, we can allow multiple clients to connect to the server simultaneously. 12.3 Implementing Multiplexing Multiplexing is a way of handling multiple clients in a single server process. The application allows clients to connect to the server and adds them to a watch list. This watch list is just an array of socket descriptors. Then the operating system tells the application which clients (if any) need to be serviced or if a new client has established a connection. We use select() system call to implement multiplexing. It allows us to specify a set of descriptors that we are interested in. It is worth noting that select() works with any descriptor, including files, pipes, FIFOs, etc. The system puts our program to sleep, polls the sockets for activity, and wakes the program when an event occurs at one of the sockets. This keeps us from writing a busy loop and wasting clock cycles. The select() function prototype looks like this:

#include <sys/select.h> int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

The first parameter specifies the highest numbered descriptor (plus 1) to watch in the three sets. It is important to remember that you must add 1 to the highest numbered descriptor in the sets. The reason is that the watch lists are linear arrays of bit values, with 1 bit for every available descriptor in the system. Next, we provide three descriptor sets. The first set contains descriptors to be watched for read events, the second for write events, and the third for exceptions or error events. Finally, we provide a timeval that specifies a

66

timeout. If no event occurs in any of the sets before the timeout, then select() returns a 0. We can also specify a null pointer for the timeout parameter. In this case, the call will not return until an event happens on one of the watched descriptors. Otherwise, it returns the number of descriptors in the three sets. It is important to note that select() does modify the descriptor sets that are passed to it. Upon return, the sets will contain only those descriptors that had some activity. To call select multiple times, we must retain a copy of the original sets. Other than a socket error, if any error occurs, then 1 is returned. Four macros are provided to help deal with the descriptor sets. They are FD_CLR, FD_ISSET, FD_SET, and FD_ZERO. Each takes a pointer to a variable type fd_set. Except for FD_ZERO, each takes a descriptor as well. It is important to note that the behavior of these macros is undefined if you pass in a descriptor that is less than zero or greater than FD_SETSIZE. The macros are prototyped as follows: void FD_SET(int fd, fd_set *set): FD_SET flags a descriptor to be watched. void FD_CLR(int fd, fd_set *set): FD_CLR resets the flag set to a descriptor. int FD_ISSET(int fd, fd_set *set): After select() returns, FD_ISSET determines whether a descriptor is flagged or not. void FD_ZERO(fd_set *set): FD_ZERO clears the set so that no descriptors are watched. Task 1: The following program watches standard input for data for 5 seconds. Please write, compile and execute the program.
#include #include #include #include <stdio.h> <sys/time.h> <sys/types.h> <unistd.h>

int main ( void ) { fd_set rfds; struct timeval tv; int retval; FD_ZERO ( &rfds ); FD_SET ( 0, &rfds ); tv.tv_sec = 5; tv.tv_usec = 0; retval = select ( 1, &rfds, NULL, NULL, &tv ); if ( retval == -1 ) perror ( "select" ); else if ( retval ) printf ( "Data is available now.\n" ); else

67

printf ( "No data within five seconds.\n" ); return 0; }

Describe for how long does this program block waiting for input?

Does this program watch for any descriptors that are ready to be written?

Does this program watch for any descriptors that have generated errors?

68

Task 2: Following program is a revised version of TCP server in lab exercise 8. This server program, however, allows multiplexing sockets so that multiple clients can connect to the server simultaneously. Write, compile and execute the program.

#include #include #include #include #include #include #include

<stdio.h> <sys/types.h> <sys/socket.h> <netdb.h> <stdlib.h> <string.h> <sys/ioctl.h>

int main ( int argc, char * argv[] ) { const char MESSAGE[] = "In the name of Allah,the Most Merciful and the Most Beneficient.\n"; int serverSocket = 0; int port = 0; int returnStatus = 0; struct sockaddr_in serverAddress; int val; int x; fd_set readset, writeset, treadset, twriteset; if ( argc != 2) { fprintf ( stderr, "Usage: %s <port>\n", argv[0] ); exit ( 1 ); } serverSocket = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( serverSocket < 0 ) { perror ( "socket" ); exit ( 1 ); } val = 1; returnStatus = setsockopt ( serverSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val) ); if ( returnStatus < 0 ) { perror ( "setsockopt" ); exit ( EXIT_FAILURE ); } port = atoi ( argv[1] ); bzero ( &serverAddress, sizeof (serverAddress) ); serverAddress.sin_family = AF_INET;

69

serverAddress.sin_addr.s_addr = htonl (INADDR_ANY); serverAddress.sin_port = htons ( port ); returnStatus = bind ( serverSocket, (struct sockaddr *)&serverAddress,sizeof (serverAddress) ); if ( returnStatus != 0 ) { perror ( "bind" ); close ( serverSocket ); exit ( 1 ); } returnStatus = listen ( serverSocket, 5 ); if ( returnStatus < 0 ) { perror ( "listen" ); close ( serverSocket ); exit ( 1 ); } FD_ZERO(&writeset); FD_ZERO(&readset); FD_SET(serverSocket, &readset); while ( 1 ) { treadset = readset; twriteset = writeset; returnStatus = select ( FD_SETSIZE, &treadset, &twriteset, NULL, NULL ); if( returnStatus < 1 ) { perror ( "select" ); exit ( 1 ); } for ( x = 0; x < FD_SETSIZE; x++ ) { if ( FD_ISSET(x, &treadset ) ) { if ( x == serverSocket ) { struct sockaddr_in clientAddress = { 0 }; int childSocket = 0; int clientAddressLength = sizeof ( clientAddress ); childSocket = accept ( serverSocket, (struct sockaddr *)&clientAddress, \ &clientAddressLength ); if ( childSocket < 0 ) { perror ( "accept" ); close ( "serverSocket" ); exit ( 1 ); }

70

FD_SET(childSocket, &writeset); } /* if ( x == serversocket ) */ } /* if ( FD_ISSET (x, &rtreadset )) */ else if ( FD_ISSET (x, &twriteset ) ) { int n; printf ( "Sending data to descriptor #%i.\n", x ); n = send ( x, MESSAGE, strlen (MESSAGE), 0 ); if ( n == strlen(MESSAGE) ) { close(x); /* close childsocket */ FD_CLR(x, &writeset); printf ( "Client on descriptor #%i disconnected.\n", x); } else { perror ( "send" ); exit(1); } } /* else if */ } /* for */ } /* while */ close ( serverSocket ); return 0; }

Task 3: Run the above program on one computer and run multiple TCP clients on different machines specifying the IP address of the server machine. Describe the result.

71

You might also like