Professional Documents
Culture Documents
Acknowledgements
Mr. Ahmad Mudassir Ms. Tabassum Nawaz Bajwa
Registration Number: ----------------Debugging 4 marks Output 2 marks Total marks Date Signature
Execution 4 marks
System Calls
Introduction to Sockets
TCP Client
TCP Server
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
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.
(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
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
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
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; };
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 */
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); }
27
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
#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
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
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
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
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(),
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
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
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
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
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.
#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
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; }
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
#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
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.
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