15-213 Recitation 9 Greg ReshkoOutlineUnix File I/OUnix File I/O: Read/WriteUnix File I/O: More RobustStandard I/O vs. Unix I/ONetworkingClient Code PathServer Code PathServer: InitServer: LoopServer: The RestLogging and Network I/OReading to/from Network & FileSlide 15Slide 16Slide 17Lab 7 – Logging Web Proxy15-213 Recitation 9Greg ReshkoOffice Hours: Wed 2:00-3:00PMApril 21st, 2003OutlineFile I/ONetworkingLab 7Unix File I/OAll I/O devices are modeled as filesNetworks, disks, terminals, etcAll input and output is performed by reading and writing the appropriate files Kernel maintains all information about files and just returns a file descriptor to an application that wants access to a given fileUnix File I/O: Read/Write#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);ssize_t write(int fd, const void *buf, size_t count);Unix File I/O: More RobustRobust I/O (RIO) Package:Unbuffered:ssize_t readn(int fd, void *buf, size_t count);ssize_t writen(int fd, const void *buf, size_t count);ssize_t readline(int fd, void *buf, size_t maxlen);Buffered (thread-safe):ssize_t readnb(int fd, void *buf, size_t count);ssize_t writenb(int fd, const void *buf, size_t count);ssize_t readlineb(int fd, void *buf, size_t maxlen);Standard I/O vs. Unix I/O Standard I/O almost always preferredfopen, fclose, fseek, fread, fwrite, fscanf, fprintf, etc.A higher-level abstraction than UNIX I/OModels files as streams, like file descriptors in being full-duplexRestrictions exist that interact badly with restrictions on socketsInput function cannot follow an output function (or vice versa) without a call to fflush, fseek, fsetpos, rewind, or and end-of-fileNetworkingTwo sides to networkingClient / ServerDistinction is fadingPeer-to-peer systems mean a node is bothClient Code PathClients typically connect to servers, perform a task, then close the connectionCreate a socket() Connect()Write()/read()Close()Server Code PathServers wait for connections and handle them as they arriveCreate a socket()Bind() to a portListen() for connectionsSelect() a ready connection Accept() a connectionRead()/Write()Close() the connectionWe’ll focus on TCP, but UDP is just as importantServer: Initvoid CreateTCPServer(){ struct sockaddr_in myAddr; int myAddrLen; int reuseAddrFlg=1; tcpSocketfd = socket(AF_INET,SOCK_STREAM,0); bzero((void *)(&myAddr),sizeof(myAddr)); myAddr.sin_family = AF_INET; myAddr.sin_port = htons((unsigned short)atoi(chatTCPServerPort)); myAddr.sin_addr.s_addr = htonl(INADDR_ANY); setsockopt(tcpSocketfd,SOL_SOCKET,SO_REUSEADDR,(void *) &reuseAddrFlg,sizeof(reuseAddrFlg)); bind(tcpSocketfd,(struct sockaddr *)&myAddr,sizeof(myAddr)); listen(tcpSocketfd,MAX_BACKLOG);}Server: Loopwhile(1){ readSet=allSet; numReadyDescriptors=select(maxfd+1,&readSet,NULL,NULL,NULL); if(FD_ISSET(tcpSocketfd,&readSet)){ /* Incoming request for new connection */ struct sockaddr_in clientAddr; int clientAddrLen; slavefd=accept(tcpSocketfd,(struct sockaddr *) &clientAddr, &clientAddrLen); /* Save slavefd so we know to check it later */ FD_SET(slavefd,&allSet); if(slavefd > maxfd) maxfd=slavefd; fflush(stdout); numReadyDescriptors--; if(numReadyDescriptors <= 0) continue; }}Server: The RestCheck whether interesting socket descriptors are in the read/write setDo appropriate action if they are (i.e., read() or write())Close() the connection when appropriateLogging and Network I/OHave a server set up to receive requests and respond to themRead in request, parse, and return responseNeed to read/write to a network stream, and log events to a file for record-keeping purposesMain loop opens file for logging and spawns children threadsEach thread has own network streams, but shares logging file streamUse of mutex to lock resources glossed over for nowReading to/from Network & Filevoid main (){ FILE* log; /* open file */ log = fopen ( "log.txt“, "a“ ); while ( true ) { /* * Main Loop (inside thread) */ } fclose ( log );}Reading to/from Network & Filevoid *thread ( void *vargp ){ FILE* stream; char method[BUFSIZE], uri[BUFSIZE], version[BUFSIZE]; /* create mutex */ /* given argument, set file descriptor for proper access to streams */ childfd = *((int *)vargp); free(vargp); /* open file descriptors for reading network socket, set buffer type */ if ((stream = fdopen(childfd, "r+")) == NULL)error("ERROR on fdopen"); setvbuf(stream, NULL, _IONBF, 0); /* get header off the stream and save */ fgets(buf, BUFSIZE, stream); sscanf(buf, "%s %s %s\n", method, uri, version);Reading to/from Network & File /* * Parse, error check, ready for server communication. */ /* * determine size of information to be written back * in this case, copying from some other stream (buf) * to the network stream (stream) */ /* get size of remaining buffer from stream */ temp = read ( serverfd, buf, BUFSIZE ); while ( temp > 0 ) { data.byte += temp; /* * write current buffered amount to network socket * get size of remaining buffer from stream */ fwrite ( buf, sizeof ( char ), temp, stream ); temp = read ( serverfd, buf, BUFSIZE ); }Reading to/from Network & File /** init mutex **/ /** lock mutex **/ /* write to log file */ fprintf(log, "%s %s %s %d\n", data.date, data.ip, data.address, data.byte); /** unlock mutex **/ /* close network buffer */ fclose(stream);}Lab 7 – Logging Web ProxyStart early (yeah, that’s a new one…)Read the book carefullyEverything you need for this lab is in the book – make sure you understand itConcurrency issuesTest it with your web browseri.e. Internet ExplorerThis is the coolest part of the
View Full Document