This assignment is Due on: Day: Wednesday, May 27, 1998 Time: Before 6:00 PM WARNINGS: TURN IN THIS ASSIGNMENT ELECTRONICALLY USING "turnin". LATE ASSIGNMENTS WILL NOT BE ACCEPTED. PLEASE NOTE CHANGE OF DUE TIME FROM PREVIOUS HOMEWORKS. ---------------------------------------------------------------------- The purpose of this homework is to reinforce explanation of the following C and UNIX programming concepts: socket(3N) connect(3N) send(3N) recv(3N) shutdown(3N) bind(3N) listen(3N) accept(3N) error checking !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! I M P O R T A N T ! ! I M P O R T A N T ! ! I M P O R T A N T ! ! THIS HOMEWORK IS DIFFERENT FROM ALL OTHER HOMEWORKS YOU HAVE HAD THIS QUARTER! GRADING WILL BE DONE BASED ON WHAT YOU TURNIN AND YOU WILL RECEIVE A WORKING GRADE BASED ON THE FUNCTIONALITY OF YOUR CODE. THIS GRADE WILL BE DETERMINED WHEN YOU MAKE CONNECTIONS TO OUR SERVER. IF YOU COMPLETE ALL STEPS OF THIS HOMEWORK AND TURNIN WHAT YOU ARE TOLD, YOU WILL RECEIVE A GRADE OF 50/50! TO RECEIVE THIS GRADE, YOU MUST FOLLOW INSTRUCTIONS TO THE LETTER. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Please remember to only turnin your answer, and NOT the questions and instructions given in this file. If you do not follow this instruction, you may lose points at the grader's discretion. What is a Socket? ----------------- Sockets are one of the most interesting forms of IPC (InterProcess Communication). They allow process on different computers (hosts) to communicate with each other over a network. Applications like web browsers, telnet, and other Internet programs all work using sockets. Once established, a socket is used much like a file (as other I/O in UNIX), so that you can send and receive data over the remote connection. References: www.wrox.com/books/680/680.stm This is the sockets chapter from "Beginning Linux Programming" (students from last qtr found this the best reference and test questions just might come from here) Bacon, pp 494-497 Socket man pages. Note that on Solaris (acmes), the sockets interface is implemented as library calls, so it will be in section 3 of the manual (3N in particular). On SunOS (richsuns) it is implemented as a system call, so it will be in section 2 of the manual. IMPORTANT -- IMPORTANT -- IMPORTANT -- IMPORTANT -- IMPORTANT To compile on a Solaris system (acmes) or SunOS (richsuns), cc -o filename filename.c -lsocket -lnsl The "-lsocket" and "-lnsl" tells the compiler to link with the appropriate libraries. ----------->Please read the reference material before beginning.<------------- In the first part of this assignment, you will implement a simple client that will connect to a server, make a request, receive some data, and possibly reply to the data. In the second part, you are given skeleton code for a simple server. It will be your task to implement full error checking and modify the server to accept connections from the CS2430 server and exchange data with it. First, modify the code in mysock.c to create a new socket, connect to the server, send a request, receive a reply, then close the connection. To do this, you will need the following functions: int socket(int domain, int, type, int protocol); /* Creates a new (unbound) socket with the given domain, type and protocol. We will be using the ARPA Internet domain of protocols, and we want reliable, two-way connection-based byte streams. Use 0 for the protocol, as this will select the default one based on the family and type. You're expected to figure out which family and type given the information in this comment (IOW: "Read the man page"). */ int connect(int s, struct sockaddr *name, int namelen); /* Connect takes a socket, and connects it to the given address. Note that the type accepted here is a struct sockaddr *, but the address structure in the code is a struct sockaddr_in. This means you will have to case this argument. */ int send(int s, const char *msg, int len, int flags); /* Send the message stored in msg, that is len bytes long over the socket s. This function returns the number of bytes sent. Be sure to take full advantage of this fact when error checking. (In otherwords, the most restrictive error test is always the best). You can assume that you will always set flags to 0. */ int recv(int s, const char *buf, int len, int flags); /* Receive a message from socket s, and write it into buffer buf, which is no more than len bytes long. Again flags will always be zero. */ int shutdown( int s, int how ); /* Close a socket connection. Read the man page to find out how "how" affects closing the socket. */ int close( int s ); /* Effectively equivalent to shutdown( s, 2 ); */ The first thing we're going to do is to connect to acmex.gatech.edu on port 13. Ports are logical (as opposed to physical) partitions of the socket space. In English, this means that ports allow you to have several sockets connected to and from each host. The server on port 13 does not require you to send any data (in fact, it will ignore anything you send) and will return only one line. (One line will easily fit into the supplied buffer: msgbuf). Refer to the supplied code for "mysock.c". Add code to do the following things: 0. Create a socket 1. Connect to server 2. Get the reply 3. Display the reply to the user 4. Close the connection Fill in the missing sections of code in "mysock.c" to complete the client. Only add code where you see "your code goes here" comments Change nothing else. For this part, you will skip the "SEND DATA" section. Now compile and test your code. Don't forget that you need to call cc with the two -l flags (see above). When you run mysock, you should get a one line response (Hint: It won't be a second too soon when you get mysock to run right). Don't continue until you have mysock.c working properly. -----------------------Start Answer Here----------------------- [p0] 5.0 points (a) Include the response you received from the server on port 13 here (b) What "service" is provided on port 13? (c) Look in /etc/services and list the name and port number of TWO other services that you use frequently. ------------------------End Answer Here------------------------ Webservers operate on the well known port number 80. Now your going to rewrite mysock.c to connect to voreg.cc.gatech.edu (aka www.cc.gatech.edu), send an HTTP request, and read the HTML file that is sent to you. This is exactly how web browsers like Netscape work, except that they interpret the HTML code and have a nice display. To make your client a pseudo web browser, you'll need to follow these steps: 1. Change the #define for the SERVER_NAME and SERVER_PORT. 2. Fill in the "SEND DATA" section of the code. Send this string to the server: "GET / HTTP/1.0\r\n" (\r is a carriage return) 3. Change the call to recv, so that it is called in loop until the web server has no more data to send. Hint: check the return value to find out when this happens. Make sure your server returns the College of Computing homepage in html format. -----------------------Start Answer Here----------------------- [p1] 5.0 points Include the complete source to your mysock.c here. ------------------------End Answer Here------------------------ Now we're going to start connecting to the CS2430 server which is on acmex.gatech.edu on port number 2430. This isn't a well known port number. (why not?) The CS2430 server accepts the following messages: getrand retrand getkey testserv We'll deal with getkey and testserv later, right now let's just look at getrand and retrand. When the server receives a "getrand" message, it generates a random unsigned integer, sends it back to the client, and waits for the "retrand" message. When your client gets the random number, it should store it, then send it back to the server with the "retrand" message. This is the first part for the "Working Grade" for this assignment. Here is a sample exchange: (server): CS2430 Server\r\n (client): (server): gt1646b authenticated. (client): getrand\r\n (server): 5432421\r\n (client): retrand 5432421\r\n (server): Congratulations! You've completed part 1. --> Server closes connection <-- --> Client closes connection <-- Note that the server always sends the "CS2430 Server" message when a connection is opened and that all lines should end with a carriage return and a newline. The authentication message is handled by a call to auth() which takes your connected socket as a parameter. We just want to make sure you are who you say you are. You must #include "auth.h" and link auth.o with your mysock.c in order for this to work. You may find it easiest to use a Makefile from the project and just change the SRC and OBJ variables and add the -lsocket and -lnsl flags. Go ahead and modify mysock.c to complete the random number portion of the working grade now. You'll need to take the following steps: 0. Change the SERVER_NAME and SERVER_PORT 1. Include a call to recv (to get the cs2430 Server message),auth() and then another call to recv (to get the server's authentication answer) immediately after you've connect()'d successfully. 2. Call send to send the "getrand" message to the server. Use recv to get the servers answer. 3. Process the server's answer, then send the "retrand" message back to the server. 4. Include one more call to recv in order to get the confirmation message from the server. Remember that debugging is virtually impossible unless you display every message sent and received to the user. Don't continue until you get this part working. Now your going to write your own server. We'll try to avoid confusion and call your server the Server Under Test (SUT). So whenever we say "the server", we really mean the CS2430 server that you interact with. If we're talking about your server, it will be "the SUT". The next few questions will require you to make several modifications to the source file(s). Please read the following steps through carefully to make sure you have a complete understanding of everything that needs to be done, BEFORE you begin. You may want to copy your original file(s) to a different directory so that you will have a backup set in the event that something doesn't go exactly right. Refer to the code in "myserv.c" - this contains some sample code for a simple server. Note that no error checking is done (it will be part of your job to correct this). You may use the function die() which prints out an error message and exits to handle all errors. There are also a couple of other socket functions used for writing servers: int bind( int s, struct sockaddr *name, int namelen ); /* This forces your socket s to be associated with the specific port number you put in the "name" structure. Namelen is just the size of the structure you are passing. The return value is an 0 if successful and -1 if there is an error. */ int listen( int s, int backlog ); /* Listen tells the system that you are "listening" to the socket to see if anyone is trying to connect() to the port that you bound your socket to. The return value is an error indication. Backlog is how many connections to queue up before you start sending "connection refused" messages to people trying to connect. */ int accept( int s, struct sockaddr *addr, int *addrlen ); /* Accept returns a socket that is now connected with the client that established a connection on the port you were listening to. Accept fills in the addr structure with the remote client's address and port number. IMPORTANT: accept expects a POINTER to an integer for the third argument. This is because it fills in the size of the addr structure that you passed a pointer to. */ In myserv.c: 0. Change the PORT_NUMBER to a number of your choice. The number must be higher than 1024 (higher is better, so over 10,000 is really good) but lower than 65535. A good choice might start with the last 4-5 digits of your Social Security number or GT number. This will avoid potential conflicts with other students' choices. YOU CAN NOT USE PORT 2430, WE ARE USING IT FOR OUR SERVER. You must also change HOST_NAME to the acme you are running your server on: acmex, acmey, or acmeyz. Actually, HOST_NAME is only used in sending the greeting to the CS2430 Server. 1. Fill in all /* your code here */ sections. You may need to refer to the man pages for the socket calls. 2. Compile myserv.c 3. You'll need two windows open and logged into (preferably) different acme's. In one window, start your SUT. In the other window, you're going to test your SUT by using telnet. For example, if you started your SUT on acmez and set the port number to 52525, you would run telnet like: telnet acmez 52525 This command instructs telnet to connect to port 52525 on acmez (rather than the normal telnet well-known port. You can interact with your server as if you were the CS2430 server in order to test it. 4. Keep doing step three until you think your server is running properly. Helpful Hints ------------- If you get an error "can't bind to port", pick a new port number. The one you picked is most likely in use. Note that a "can't bind to port" message is sometimes normal. After use, the system 'reserves' the port number for a set period of time before it can be used again. This time varies from system to system and is usually at least 2 minutes but no more than 4 minutes. If you have to restart your server alot, you might get sick of having to wait for the system to let you bind to your port again, or recompiling everytime. You might choose to pass in the port number as a command line argument (i.e. through argv). -----------------------Start Answer Here----------------------- [p2] 10.0 points Include your entire myserv.c code here: ------------------------End Answer Here------------------------ Here is where the real fun begins. Now, you will use your client and server to communicate with our class server. This server will log all of your transactions. If you successfully complete all steps below (and you include above answers), you will get a grade of 50/50. If you fail to get all steps below working or you choose not to do this section, your grade will be based solely on the above problems. In this case, your grade will be at most 20/50. But if you got this far, you should be able to finish with no problem! The 2430 Server: Our server is a transaction-based server, much like the web server you connected to above. You will create a transaction string, send it to the server, and receive the response. In this case, your client will ask for a part of speech, then tell the server where your SUT is. The cs2430 server will connect to your SUT, and ask for your answer. In otherwords, your client may find out that we want a noun, so you might tell your SUT to tell the cs2430 server "banana". What's the point? You're filling out a madlib. There will be several created, and when each one is completely filled in, it will be posted to the web (along with a list of contributors at the bottom). For those who don't know: a madlib is basically a game where, given a part of speech (noun, person, boy's name, place, etc.) you choose word. This word is used in a prewritten story. You're not supposed to know what the story is, so the resulting story (with your words filled in) is supposed to be funny. Of course, we know who submits which words; vulgar, obscene, or offensive language is not acceptable. Sorry, that just had to be said. On to the instructions: ----->YOU MUST RUN YOUR CLIENT / SERVER ON ACME FROM HERE ON!<------- OUR SERVER WILL NOT RECOGNIZE YOU IF YOU AREN'T CONNECTING FROM ACME! The 2430 server is located at: acmex.gatech.edu, port 2430 PLEASE WATCH THE NEWSGROUP FOR ANY ANNOUNCEMENTS ABOUT THE 2430 SERVER. For example, it may crash from time to time. When it does, it should automatically restart, however, it may not be able to bind to port 2430 for 2 - 4 minutes. Moral of the story? Start on time and don't crash the sever, and everyone will be able to complete the homework on time. Test your code on your own before you attempt to use it with the 2430 server. You can also telnet to acmex, port 2431 to get a message regarding the current status of the server (it's automated -- In other words, it won't always be 100% accurate). This should be useful if you can't tell if the server is down, or if your client is flawed. The client/server/SUT interaction follows this sequence. 0. Your client connects with the 2430 server on port 2430 of acmex. 1. The server will send you the standard CS2430 Server greeting. 2. You client must call the auth() function and received the authentication confirmation like before. 3. Your client must then request a part of speech and a key (so the server knows where to put your answer). This is the "getkey" message we saw above. 4. The server will send you a part of speech and a key and then close the connection. Your client should also close the connection at this point. You should be able to figure out how to modify mysock.c to accomplish this part. Be sure that your client prints out all messages sent and received. That way, you know what part of speech you have and what your key is. Now you have 2 hours to go set your SUT up and tell the cs2430 server where it is so you can give your answer back. After that, your key expires, and you will have to repeat the part above. Put the key and your answer into the "RESPONSE" #define in myserv.c. Now you have to tell the cs2430 server where your server is: 0. Modify mysock.c so that it will send a "testserv" message (defined way above) to the cs2430 server. 1. Start your SUT. 2. Run your client. It should connect to the cs2430 server, and give the testserv message. At that point, the server will connect to your SUT and try to get your answer from it. 3. The cs2430 server will tell your *client* whether or not the SUT performed correctly. If it got a valid key and answer, then you win. Congratulations. The server is single-threaded. This means that it can only handle one request at a time. So, you might get a 'busy signal'; keep trying if you do. DO NOT WAIT UNTIL THE LAST DAY BEFORE THIS IS DUE TO ATTEMPT CONTACT WITH THE 2430 SERVER!!!!! YOU ARE WELL ADVISED TO GET STARTED EARLY AS TO AVOID THE RUSH. -----------------------Start Answer Here----------------------- [p3] 30.0 points Paste all output from your server transactions here. Please note that if everything works correctly, AND you include your 'complete' responses to p0-p3 , then you will get the full 50 points. ------------------------End Answer Here------------------------