240 likes | 342 Views
Homework 1 Design Issues. 1) The server should be concurrent. This implies that it should loop infinitely, listening for clients requests. It should NOT terminate after accepting the first connection. while( 1 ) /* loop forever */ { /* recieve a new connection */
E N D
Homework 1 Design Issues 1) The server should be concurrent. This implies that it should loop infinitely, listening for clients requests. It should NOT terminate after accepting the first connection. while( 1 ) /* loop forever */ { /* recieve a new connection */ newSocketDes = getConnection( socketDes, socketInfo ); if( fork() == 0 ){ close( socketDes ); /* retrive the filename */ getFileName( newSocketDes, fileName ); /* Get the requested data */ retrieveData( newSocketDes, fileName ); exit( 0 ); }
Homework 1 Design Issues close( newSocketDes ); } exit( 0 ); } 2) The names for the requested and delivered files should be the same. /* send the file name */ sendMessage( socketDes, argv[ 3 ] ); /* get the file */ getMessage( socketDes, argv[ 3 ] );
Homework1 Design Issues 3. The size of the file after the transfer should be the same as that on the server. That is, no extra characters should be written by the server or the client. Server side int result = 1; fileDes = open( fileName, O_RDONLY ); while( result > 0 ) { /* read the info */ result = read( fileDes, message, MAXBUF ); /* write the info */ if( result != -1 ) write( socketDes, message, result ); } /* We are all done, close the file */ close( fileDes );
Homework1 Design Issues Client side int messageLength = 1; /* Open the file in write mode */ fd = open( filename, O_CREAT|O_RDWR,S_IREAD|S_IWRITE); while( messageLength > 0) { /* get the file from the socket */ messageLength = read( socketDes, message, MAXBUF ); if( messageLength != 0) /* Write the contents of the file (message) into the file */ write(fd, message, messageLength); }
Homework1 Design Issues 4. Preferably, the rate at which you are sending the data (number of writes and reads to/from the socket) should be optimized. This means that the maximum possible number of bytes must be read/written per read/write call. You should be able to easily change this number without affecting the rest of the program (for example, by changing MAXBUF value in common.h, without any changes to other C files). #define MAXBUF 1024 /* maximum buffer size for reading and writing messages */
FTP RFC (Request For Comments) 959 http://www.ietf.org/rfc.html The File Transfer Protocol was defined as a protocol for file transfer between HOSTs on the ARPANET, with the primary function of FTP defined as transferring files efficiently and reliably among hosts and allowing the convenient use of remote file storage capabilities. There are 2 channels: • Control Channel (port 21) FTP commands and replies Eg: ftp draco Connected to draco.ece.arizona.edu. 220 gauss FTP server (SunOS 5.8) ready. 2. Data Channel (port 20)
THE FTP MODEL User Interface User FTP Commands Server PI User PI FTP Replies Server DTP Data File system File system User DTP Connection Server Side Client Side
FTP PI Protocol Interpreter DTP Data Transfer Process Examples of protocol interpretation Client Server ls STAT . get retr put stor
Connection Oriented Protocol Server socket() bind() listen() accept() Client blocks until connection from client socket() connection establishment connect() read() data(request) write() process request write() data (reply) read()
Connectionless Protocol Server socket() bind() recvfrom() Client blocks until connection from client socket() bind() data (request) sendto() process request write() data (reply) recvfrom()
System Calls int sendto (int socket, char *message, int nbytes, int flags, struct sockaddr *dest, int dest_len); Description The sendto() function sends a message through connectionless-mode socket.The message will be sent to the address specified by dest. The system call takes the following arguments: socket Specifies the socket descriptor. message Points to a buffer containing the message to be sent. nbytes Specifies the size of the message in bytes.
System Calls dest Points to a sockaddr structure containing the destination address. The length and format of the address depend on the address family of the socket. dest_len Specifies the length of the sockaddr structure pointed to by the dest argument. flags Values of this argument are formed by logically OR'ing zero or more of the following flags
System Calls int recvfrom (int socket, char *message, int nbytes int flags, struct sockaddr *from, int *from_len); Description The recvfrom() function call receives a message from a connectionless-mode socket. The recvfrom system call fills in the protocol specific address of who sent the data into from . The length of this address is also returned to the caller in from_len.
UDP Echo Server /* * Header file */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define SERV_UDP_PORT 6000 #define SERV_HOST_ADDR "128.196.28.78" /* host addr for server */
UDP Echo Server /* * Example of server using UDP protocol. */ #include "inet.h" main(argc, argv) int argc; char *argv[]; { int sockfd; struct sockaddr_in serv_addr, cli_addr; /* * Open a UDP socket (an Internet datagram socket). */ if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) perror("server: can't open datagram socket");
UDP Echo Server /* * Bind our local address so that the client can send to us. */ bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_UDP_PORT); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) perror("server: can't bind local address"); dg_echo(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)); }
UDP Echo Server /* * Example of client using UDP protocol. */ #include "inet.h" main(argc, argv) int argc; char *argv[]; { int sockfd; struct sockaddr_in cli_addr, serv_addr; /* * Fill in the structure "serv_addr" with the address of the * server that we want to send to. */ bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);
UDP Echo Server serv_addr.sin_port = htons(SERV_UDP_PORT); /* * Open a UDP socket (an Internet datagram socket). */ if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) perror("client: can't open datagram socket"); /* * Bind any local address for us. */ bzero((char *) &cli_addr, sizeof(cli_addr)); /* zero out */ cli_addr.sin_family = AF_INET; cli_addr.sin_addr.s_addr = htonl(INADDR_ANY); cli_addr.sin_port = htons(0); if (bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0) perror("client: can't bind local address");
UDP Echo Server dg_cli(stdin, sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); close(sockfd); exit(0); }
UDP Echo Server /* * Read a datagram from a connectionless socket and write it back to * the sender. * dg_echo() * We never return, as we never know when a datagram client is done. */ #include <sys/types.h> #include <sys/socket.h> #define MAXMESG 2048 dg_echo(sockfd, pcli_addr, maxclilen) int sockfd; struct sockaddr *pcli_addr; /* ptr to appropriate sockaddr_XX structure */ int maxclilen; /* sizeof(*pcli_addr) */ { int n, clilen; char mesg[MAXMESG];
UDP Echo Server for ( ; ; ) { clilen = maxclilen; n = recvfrom(sockfd, mesg, MAXMESG, 0, pcli_addr, &clilen); } if (n < 0) perror("dg_echo: recvfrom error"); if (sendto(sockfd, mesg, n, 0, pcli_addr, clilen) != n) perror("dg_echo: sendto error"); } }
UDP Echo Server /* * Read the contents of the FILE *fp, write each line to the * datagram socket, then read a line back from the datagram * socket and write it to the standard output. *dg_cli() * Return to caller when an EOF is encountered on the input file. */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #define MAXLINE 512 dg_cli(fp, sockfd, pserv_addr, servlen) FILE *fp; int sockfd; struct sockaddr *pserv_addr; /* ptr to appropriate sockaddr_XX structure */ int servlen; /* actual sizeof(*pserv_addr) */ {
UDP Echo Server int n; char sendline[MAXLINE], recvline[MAXLINE + 1]; while (fgets(sendline, MAXLINE, fp) != NULL) { n = strlen(sendline); if (sendto(sockfd, sendline, n, 0, pserv_addr, servlen) != n) perror("dg_cli: sendto error on socket"); /* * Now read a message from the socket and write it to * our standard output. */ n = recvfrom(sockfd, recvline, MAXLINE, 0, (struct sockaddr *) 0, (int *) 0); if (n < 0) perror("dg_cli: recvfrom error"); recvline[n] = 0; /* null terminate */ fputs(recvline, stdout); }
UDP Echo Server if (ferror(fp)) perror("dg_cli: error reading file"); }