More Network Programming

Similar documents
UNIT III - APPLICATION DEVELOPMENT. TCP Echo Server

Any of the descriptors in the set {1, 4} have an exception condition pending

pthreads CS449 Fall 2017

ISA 563: Fundamentals of Systems Programming

POSIX threads CS 241. February 17, Copyright University of Illinois CS 241 Staff

ECE 650 Systems Programming & Engineering. Spring 2018

CSCE 313 Introduction to Computer Systems. Instructor: Dezhen Song

CSE 333 SECTION 9. Threads

UNIX System Calls. Sys Calls versus Library Func

Socket programming in C

CSC209: Software tools. Unix files and directories permissions utilities/commands Shell programming quoting wild cards files

CSC209: Software tools. Unix files and directories permissions utilities/commands Shell programming quoting wild cards files. Compiler vs.

Εργαστήριο 9 I/O Multiplexing

CSE 333 SECTION 3. POSIX I/O Functions

CISC2200 Threads Spring 2015

Overview. Administrative. * HW 2 Grades. * HW 3 Due. Topics: * What are Threads? * Motivating Example : Async. Read() * POSIX Threads

I/O OPERATIONS. UNIX Programming 2014 Fall by Euiseong Seo

NETWORK AND SYSTEM PROGRAMMING. I/O Multiplexing: select and poll function

CSE 333 SECTION 3. POSIX I/O Functions

CSE 410: Systems Programming

Lecture 3. Introduction to Unix Systems Programming: Unix File I/O System Calls

I/O OPERATIONS. UNIX Programming 2014 Fall by Euiseong Seo

Network programming(ii) Lenuta Alboaie

CS 3013 Operating Systems WPI, A Term Assigned: Friday, August 31, 2007 Due: Monday, September 17, 2007

CSci 4061 Introduction to Operating Systems. (Threads-POSIX)

NETWORK PROGRAMMING. Ipv4 and Ipv6 interoperability

LSN 13 Linux Concurrency Mechanisms

Introduction to Network Programming in C/C++

Section 3: File I/O, JSON, Generics. Meghan Cowan

Threads. lightweight processes

Network Programming TDC 561

Processes. Processes (cont d)

CSC209 Review. Yeah! We made it!

Operating Systems. Lecture 06. System Calls (Exec, Open, Read, Write) Inter-process Communication in Unix/Linux (PIPE), Use of PIPE on command line

Project 3. Reliable Data Transfer over UDP. NTU CSIE Computer Networks 2011 Spring

CSE 124 Discussion Section Sockets Programming 10/10/17

Lecture 4 Threads. (chapter 4)

Concurrent Programming. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

Multithreaded Programming

10. I/O System Library

CSC209H Lecture 10. Dan Zingaro. March 18, 2015

Chapter 10. Threads. OS Processes: Control and Resources. A process as managed by the operating system groups together:

POSIX Shared Memory. Linux/UNIX IPC Programming. Outline. Michael Kerrisk, man7.org c 2017 November 2017

CSC 271 Software I: Utilities and Internals

POSIX Threads. Paolo Burgio

CPSC 341 OS & Networks. Threads. Dr. Yingwu Zhu

CS 3305 Intro to Threads. Lecture 6

Introduction to Network Programming using C/C++

CS240: Programming in C

Threads. Threads (continued)

Preview. What are Pthreads? The Thread ID. The Thread ID. The thread Creation. The thread Creation 10/25/2017

Naked C Lecture 6. File Operations and System Calls

CSCI4430 Data Communication and Computer Networks. Pthread Programming. ZHANG, Mi Jan. 26, 2017

EPL372 Lab Exercise 2: Threads and pthreads. Εργαστήριο 2. Πέτρος Παναγή

Concurrent Server Design Multiple- vs. Single-Thread

Process Creation in UNIX

IPv4 and ipv6 INTEROPERABILITY

Concurrent Programming. Concurrent Programming with Processes and Threads

ECE 598 Advanced Operating Systems Lecture 23

Lecture 7. Followup. Review. Communication Interface. Socket Communication. Client-Server Model. Socket Programming January 28, 2005

Threads. studykorner.org

I/O Models. Kartik Gopalan

Operating systems. Lecture 7

Creating Threads. Programming Details. COMP750 Distributed Systems

Lecture files in /home/hwang/cs375/lecture05 on csserver.

A Socket Example. Haris Andrianakis & Angelos Stavrou George Mason University

CS 326: Operating Systems. Process Execution. Lecture 5

Systems Programming. COSC Software Tools. Systems Programming. High-Level vs. Low-Level. High-Level vs. Low-Level.

System Calls. Library Functions Vs. System Calls. Library Functions Vs. System Calls

THREADS. Jo, Heeseung

Maria Hybinette, UGA. ! One easy way to communicate is to use files. ! File descriptors. 3 Maria Hybinette, UGA. ! Simple example: who sort

ECE 435 Network Engineering Lecture 2

Redesde Computadores(RCOMP)

Processes often need to communicate. CSCB09: Software Tools and Systems Programming. Solution: Pipes. Recall: I/O mechanisms in C

COMP/ELEC 429/556 Introduction to Computer Networks

CONCURRENCY MODEL. UNIX Programming 2014 Fall by Euiseong Seo

Thread. Disclaimer: some slides are adopted from the book authors slides with permission 1

pthreads Announcement Reminder: SMP1 due today Reminder: Please keep up with the reading assignments (see class webpage)

Processes and Threads

Assignment 2 Group 5 Simon Gerber Systems Group Dept. Computer Science ETH Zurich - Switzerland

CSC209H Lecture 11. Dan Zingaro. March 25, 2015

Introduction to pthreads

Tutorial on Socket Programming

Signal Example 1. Signal Example 2

Types (Protocols) Associated functions Styles We will look at using sockets in C Java sockets are conceptually quite similar

Computer Network Programming

Network Programming in C: The Berkeley Sockets API. Networked Systems 3 Laboratory Sessions

Thread Concept. Thread. No. 3. Multiple single-threaded Process. One single-threaded Process. Process vs. Thread. One multi-threaded Process

File Descriptors and Piping

Asynchronous Events on Linux

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

Ports under 1024 are often considered special, and usually require special OS privileges to use.

Multiprocessors 2007/2008

Redes de Computadores (RCOMP)

ECE 435 Network Engineering Lecture 2

NETWORK PROGRAMMING. Instructor: Junaid Tariq, Lecturer, Department of Computer Science

SOCKET PROGRAMMING. What is a socket? Using sockets Types (Protocols) Associated functions Styles

Memory management. Johan Montelius KTH

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

CSCI 4210 Operating Systems CSCI 6140 Computer Operating Systems Sample Exam 2 Questions (document version 1.0)

Transcription:

More Network Programming

More Network Programming HTTP push server Request framing and server push concepts Demo Useful API s select/poll and advanced sockets tidbits threads HTTP push server code Components Flow charts Code walk-through (code is online) 10/11/06 UIUC - CS/ECE 438, Fall 2006 2

HTTP Request Framing Characteristics ASCII-based (human readable) Framed by text lines First line is command Remaining lines are additional data Blank line ends request frame 10/11/06 UIUC - CS/ECE 438, Fall 2006 3

HTTP Request Framing Characteristics ASCII-based (human readable) Framed by text lines First line is command Remaining lines are additional data Blank line ends request frame GET /surf/too/much.html HTTP/1.0 Date: 28 February 2006 11:25:53 CST Host: www.surfanon.org <blank line> 10/11/06 UIUC - CS/ECE 438, Fall 2006 3

HTTP Server Push Idea Connection remains open Server pushes down new data as needed Termination Any time by server Stop loading (or reload) by client Components Header indicating multiple parts New part replaces old part New part sent any time Wrappers for each part 10/11/06 UIUC - CS/ECE 438, Fall 2006 4

HTTP Server Push 10/11/06 UIUC - CS/ECE 438, Fall 2006 5

HTTP Server Push HTTP/1.0 200 OK Content-type: multipart/x-mixed-replace;\ boundary=---never_in_document--- ---never_in_document--- 10/11/06 UIUC - CS/ECE 438, Fall 2006 5

HTTP Server Push HTTP/1.0 200 OK Content-type: multipart/x-mixed-replace;\ boundary=---never_in_document--- ---never_in_document--- the data component 10/11/06 UIUC - CS/ECE 438, Fall 2006 5

HTTP Server Push HTTP/1.0 200 OK Content-type: multipart/x-mixed-replace;\ boundary=---never_in_document--- ---never_in_document--- the data component Content-type: text/html (actual data) ---never_in_document--- 10/11/06 UIUC - CS/ECE 438, Fall 2006 5

HTTP Push Server Demonstration Server running on port 5012 File of interest: test.html Driven by unrelated process (not the server) Changes every 2 seconds Alternates between 13 files (a through m) Demonstration Server detects file changes Pushes update after every change 10/11/06 UIUC - CS/ECE 438, Fall 2006 6

More Network Programming Useful Application Programming Interfaces Topics More advanced sockets Unix file functionality Multithreaded programming (Posix Threads) Specific APIs select/poll and advanced sockets Threads Attributes Creation Thread-specific data Minor synchronization 10/11/06 UIUC - CS/ECE 438, Fall 2006 7

Select and Poll Building timeouts with select/poll Similar functions Notes Parameters Set of file descriptors Set of events for each descriptor Timeout length Return value Set of file descriptors Events for each descriptor Select is somewhat simpler Poll supports more events 10/11/06 UIUC - CS/ECE 438, Fall 2006 8

Select and Poll: Prototypes Select: Wait for readable/writable file descriptors #include <sys/time.h> int select (int num_fds, fd_set* read_set, fd_set* write_set, fd_set* except_set, struct timeval* timeout); Poll: Poll file descriptors for events #include <poll.h> int poll (struct pollfd* pfds, nfds_t nfds, int timeout); 10/11/06 UIUC - CS/ECE 438, Fall 2006 9

Select int select (int num_fds, fd_set* read_set, fd_set* write_set, fd_set* except_set, struct timeval* timeout); Wait for readable/writable file descriptors. Return: Number of descriptors ready -1 on error, sets errno Parameters: num_fds: number of file descriptors to check, numbered from 0 read_set, write_set, except_set: Sets (bit vectors) of file descriptors to check for the specific condition timeout: Time to wait for a descriptor to become ready 10/11/06 UIUC - CS/ECE 438, Fall 2006 10

File Descriptor Sets Bit vectors Often 1024 bits (FD_SETSIZE) Only first num_fds checked Macros to create and check sets fds_set myset; void FD_ZERO (&myset); /* clear all bits */ void FD_SET (n, &myset); /* set bits n to 1 */ void FD_CLEAR (n, &myset); /* clear bit n */ int FD_ISSET (n, &myset); /* is bit n set? */ 10/11/06 UIUC - CS/ECE 438, Fall 2006 11

File Descriptor Sets Three conditions to check for Readable: Data available for reading Writable: Buffer space available for writing Exception: Out-of-band data available (TCP) 10/11/06 UIUC - CS/ECE 438, Fall 2006 12

Timeout Structure struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ }; 10/11/06 UIUC - CS/ECE 438, Fall 2006 13

Select High-resolution sleep function All descriptor sets NULL Positive timeout Wait until descriptor(s) become ready At least one descriptor in set timeout NULL Wait until descriptor(s) become ready or timeout occurs At least one descriptor in set Positive timeout Check descriptors immediately (poll) At least one descriptor in set 0 timeout 10/11/06 UIUC - CS/ECE 438, Fall 2006 14

Select: Example fd_set my_read; FD_ZERO(&my_read); FD_SET(0, &my_read); if (select(1, &my_read, NULL, NULL) == 1) { ASSERT(FD_ISSET(0, &my_read); /* data ready on stdin */ 10/11/06 UIUC - CS/ECE 438, Fall 2006 15

Poll #include <poll.h> int poll (struct pollfd* pfds, nfds_t nfds, int timeout); Poll file descriptors for events. Return: Number of descriptors with events -1 on error, sets errno Parameters: pfds: nfds: An array of descriptor structures. File descriptors, desired events and returned events Length of the pfds array timeout: Timeout value in milliseconds 10/11/06 UIUC - CS/ECE 438, Fall 2006 16

Descriptors Structure struct pollfd { int fd; /* file descriptor */ short events; /* queried event bit mask */ short revents; /* returned event mask */ Note: Any structure with fd < 0 is skipped 10/11/06 UIUC - CS/ECE 438, Fall 2006 17

Event Flags POLLIN: data available for reading POLLOUT: Buffer space available for writing POLLERR: Descriptor has error to report POLLHUP: Descriptor hung up (connection closed) POLLVAL: Descriptor invalid 10/11/06 UIUC - CS/ECE 438, Fall 2006 18

Poll High-resolution sleep function 0 nfds Positive timeout Wait until descriptor(s) become ready nfds > 0 timeout INFTIM or -1 Wait until descriptor(s) become ready or timeout occurs nfds > 0 Positive timeout Check descriptors immediately (poll) nfds > 0 0 timeout 10/11/06 UIUC - CS/ECE 438, Fall 2006 19

Poll: Example struct pollfd my_pfds[1]; my_pfds[0].fd = 0; my_pfds[0].events = POLLIN; if (poll(&my_pfds, 1, INFTIM) == 1) { ASSERT (my_pfds[0].revents & POLLIN); /* data ready on stdin */ 10/11/06 UIUC - CS/ECE 438, Fall 2006 20

Advanced Sockets signal (SIGPIPE, SIG_IGN); Call at start of main in server Allows you to ignore broken pipe signals which are degenerated when you write to a socket that has already been closed on the other side Default handler exits (terminates process) 10/11/06 UIUC - CS/ECE 438, Fall 2006 21

Advanced Sockets int yes = 1; setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof (yes)); Call just before bind Allows bind to succeed despite the existence of existing connections in the requested TCP port Connections in limbo (e.g. lost final ACK) will cause bind to fail 10/11/06 UIUC - CS/ECE 438, Fall 2006 22

Posix Threads (pthreads) When coding Include <pthread.h> first in all source files When compiling Use compiler flag D_REENTRANT When linking Link library -lpthread 10/11/06 UIUC - CS/ECE 438, Fall 2006 23

pthreads Attributes Attributes Data structure pthread_attr_t Set of choices for a thread Passed in thread creation routine Choices Inherit scheduling specifics from parent thread? Compete at process or thread level? Scheduling policy Thread priority Detached state Join operation required at termination? Only useful if thread returns a value 10/11/06 UIUC - CS/ECE 438, Fall 2006 24

pthreads Attributes Initialize an attributes structure to the default values int pthread_attr_init (pthread_attr_t* attr); Set the detached state value in an attributes structure int pthread_attr_setdetachedstate (pthread_attr_t* attr, int value); Value PTHREAD_CREATE_DETACHED PTHREAD_CREATE_JOINABLE 10/11/06 UIUC - CS/ECE 438, Fall 2006 25

pthread Error Handling pthreads functions do not follow the usual Unix conventions Similarity: Returns 0 on success Differences: Return error code on failure Does not set errno What about errno? Each thread has its own Define _REENTRANT (-D_REENTRANT switch to compiler) when using pthreads 10/11/06 UIUC - CS/ECE 438, Fall 2006 26

pthread Creation int pthread_create (pthread_t* tid, pthread_attr_t* attr, void*(child_main), void* arg); Spawn a new posix thread Parameters: tid: attr: Unique thread identifier returned from call Attributes structure used to define new thread Use NULL for default values child_main: arg: Main routine for child thread Takes a pointer (void*), returns a pointer (void*) Argument passed to child thread 10/11/06 UIUC - CS/ECE 438, Fall 2006 27

pthread Cleanup Problem A thread can be terminated by an external source (i.e. by other threads) Deallocation an other cleanup must still be performed Solution Push and pop cleanup routines Defer external cancellation until after perfroming cleanup to avoid race conditions 10/11/06 UIUC - CS/ECE 438, Fall 2006 28

pthread Cleanup { pthread_cleanup_push (my_cleanup, heap_data); { } } pthread_setcancel_type(pthread_cancel_deferred, &old); pthread_cleanup_pop(1); 10/11/06 UIUC - CS/ECE 438, Fall 2006 29

pthread Cleanup Pitfalls your code... if (i_need_a_cleanup) { pthread_cleanup_push (my_cleanup, my_arg); } /* some code outside the cleanup logic */ if (i_need_a_cleanup) { pthread_cleanup_pop (1); } 10/11/06 UIUC - CS/ECE 438, Fall 2006 30

pthread Cleanup Pitfalls what your code becomes... if (i_need_a_cleanup) { { /* code to push cleanup */ /* PUSH translation */ } /* THIS CODE IS NOW IN THE CLEANUP LOGIC! */ /* some code outside the cleanup logic */ if (i_need_a_cleanup) { } /* code to exec cleanup */ }/* POP translation */ 10/11/06 UIUC - CS/ECE 438, Fall 2006 31

Unix Files #include <sys/stat.h> int stat(const char* name, struct stat* buf); Get information about a file Returns: 0 on success -1 on error, sets errno Parameters: name: Path to file. Absolute paths begin with /, relative paths do not buf: Statistics structure off_t st_size: Size in bytes time_t st_mtime: Date of last modification. Seconds since January 1, 1970 10/11/06 UIUC - CS/ECE 438, Fall 2006 32

Unix File Operations Open (and/or create) a file for reading, writing or both int open (const char* name, in flags); Read data from one buffer to file descriptor size_t read (int fd, void* buf, size_t cnt); Write data from file descriptor into buffer size_t write (int fd, void* buf, size_t cnt); Close a file int close(int fd); 10/11/06 UIUC - CS/ECE 438, Fall 2006 33

File: Open #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open (const char* name, int flags); Open (and/or create) a file for reading, writing or both Returns: New file descriptor on success ( 0) -1 on error, sets errno Parameters: name: Path to file, absolute or relative flags: O_RDONLY: read only, O_WRONLY: write only, O_RDWR: read and write, O_CREAT: create file if it doesn t exist, O_EXCL: prevent creation if it already exists 10/11/06 UIUC - CS/ECE 438, Fall 2006 34

File: Read #include <unistd.h> size_t read (int fd, void* buf, size_t cnt); Read data from one buffer to file descriptor Return: Number of bytes read on success -1 on error, sets errno -1 on signal interrupt, sets errno to EINTR Parameters: fd: file descriptor buf: buffer to read data from cnt: length of buffer Can return < cnt for sockets without reaching end of files Returns 0 on end of file 10/11/06 UIUC - CS/ECE 438, Fall 2006 35

File: Write #include <unistd.h> size_t write (int fd, void* buf, size_t cnt); Write data from file descriptor into buffer Return: Number of bytes written on success -1 on error, sets errno -1 on signal interrupt, sets errno to EINTR Parameters: fd: file descriptor buf: buffer to write data to cnt: length of buffer Can return < cnt for sockets without reaching end of files Returns 0 on end of file 10/11/06 UIUC - CS/ECE 438, Fall 2006 36

File: Close #include <unistd.h> int close(int fd); Close a file Return: 0 on success -1 on error, sets errno Parameters: fd: file descriptor 10/11/06 UIUC - CS/ECE 438, Fall 2006 37

Multithreading-Safe Functions Functions in original libraries Use static storage Not compatible with multiple threads Reentrant versions Dubbed <name>_r Pass state back and forth to routine Example: Tokenizing a string using state local to the current thread char* strtok_r (char* s, const char* delim, char** last_p); 10/11/06 UIUC - CS/ECE 438, Fall 2006 38

Multithreading-Safe Functions char* strtok_r (char* s, const char* delim, char** last_p); Tokenizing a string using state local to the current thread Used to split up words in English text, for example, or commands and arguments given in a command line Parameters: s: The string on the first call, NULL afterwards delim: Characters that separate the tokens last_p: Storage for a pointer to the end of the last token 10/11/06 UIUC - CS/ECE 438, Fall 2006 39

Example Server similar to last MP Push server Client-server connection remains open Server pushes new data Use pthreads Main thread Accepts new client connections Spawns child thread for each client Child threads Parses client requests Constructs response Checks for file modification Pushes file when necessary 10/11/06 UIUC - CS/ECE 438, Fall 2006 40

Example: Server Thread Flow Chart 10/11/06 UIUC - CS/ECE 438, Fall 2006 41

Example: Server Thread Flow Chart Start 10/11/06 UIUC - CS/ECE 438, Fall 2006 41

Example: Server Thread Flow Chart Start Set up server TCP socket 10/11/06 UIUC - CS/ECE 438, Fall 2006 41

Example: Server Thread Flow Chart Start Set up server TCP socket Initialize thread attributes structure 10/11/06 UIUC - CS/ECE 438, Fall 2006 41

Example: Server Thread Flow Chart Start Set up server TCP socket Initialize thread attributes structure Create a thread specific data structure 10/11/06 UIUC - CS/ECE 438, Fall 2006 41

Example: Server Thread Flow Chart Start Set up server TCP socket Initialize thread attributes structure Wait for a connection Create a thread specific data structure 10/11/06 UIUC - CS/ECE 438, Fall 2006 41

Example: Server Thread Flow Chart Start Set up server TCP socket Initialize thread attributes structure Spawn a child thread to handle new connection Wait for a connection Create a thread specific data structure 10/11/06 UIUC - CS/ECE 438, Fall 2006 41

Example: Server Thread Flow Chart Start Set up server TCP socket Initialize thread attributes structure Spawn a child thread to handle new connection Wait for a connection Create a thread specific data structure 10/11/06 UIUC - CS/ECE 438, Fall 2006 41

Example: Client Thread Flow Chart 10/11/06 UIUC - CS/ECE 438, Fall 2006 42

Example: Client Thread Flow Chart Start 10/11/06 UIUC - CS/ECE 438, Fall 2006 42

Example: Client Thread Flow Chart Start Push thread cleanup function 10/11/06 UIUC - CS/ECE 438, Fall 2006 42

Example: Client Thread Flow Chart Start Push thread cleanup function n Wait for 1 second or until client send request Need to send? n Got client request? 10/11/06 UIUC - CS/ECE 438, Fall 2006 42

Example: Client Thread Flow Chart Start Push thread cleanup function n Wait for 1 second or until client send request Need to send? Store file name and reset send time n y Got client request? y Request valid? 10/11/06 UIUC - CS/ECE 438, Fall 2006 42

Example: Client Thread Flow Chart Start Push thread cleanup function n Wait for 1 second or until client send request Send file to client y Need to send? n Got client request? y Success in send? y Store file name and reset send time y Request valid? 10/11/06 UIUC - CS/ECE 438, Fall 2006 42

Example: Client Thread Flow Chart Start Push thread cleanup function n Wait for 1 second or until client send request Send file to client y Need to send? n Got client request? y Success in send? Done y Store file name and reset send time y Pop and execute thread cleanup function Request valid? n 10/11/06 UIUC - CS/ECE 438, Fall 2006 42

Example: Client Thread Flow Chart Start Push thread cleanup function n Wait for 1 second or until client send request Send file to client y Need to send? n Got client request? y Success in send? n Done y Store file name and reset send time y Pop and execute thread cleanup function Request valid? n 10/11/06 UIUC - CS/ECE 438, Fall 2006 42

Makefile CFLAGS = -g -D_REENTRANT Wall OFILES = pushy.o push_thr_code.o read_line.o \\ print_error.o all: pushy pushy: ${OFILES} gcc -g -o $@ ${OFILES} lpthread -lxnet %.o: %.c gcc -c ${CFLAGS} -O9 -o $@ $< clean: rm -f pushy query *.o *~ 10/11/06 UIUC - CS/ECE 438, Fall 2006 43

set_up_server_socket static int set_up_server_socket (u_short port) { int fd; /* server socket file descriptor */ int yes = 1; /* used for setting socket options */ struct sockaddr_in addr; /* server socket address */ /* Create a TCP socket. */ if ((fd = socket (PF_INET, SOCK_STREAM, 0)) == -1) { perror ("set_up_server_socket/socket"); return -1; } /* Allow port reuse with the bind below. */ if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof (yes)) == -1) { perror ("set_up_server_socket/setsockopt"); return -1; } 10/11/06 UIUC - CS/ECE 438, Fall 2006 44

set_up_server_socket } /* Set up the address. */ bzero (&addr, sizeof (addr)); addr.sin_family = AF_INET; /* Internet address */ addr.sin_addr.s_addr = INADDR_ANY; /* fill in local IP address */ addr.sin_port = htons (port); /* port specified by caller*/ /* Bind the socket to the port. */ if (bind (fd, (struct sockaddr*)&addr, sizeof (addr)) == -1) { perror ("set_up_server_socket/bind"); return -1; } /* Listen for incoming connections (socket into passive state). */ if (listen (fd, BACKLOG) == -1) { perror ("set_up_server_socket/listen"); return -1; } /* The server socket is now ready. */ return fd; 10/11/06 UIUC - CS/ECE 438, Fall 2006 45

wait_for_connections static void wait_for_connections (int fd){ pthread_attr_t attr; /* initial thread attributes */ thread_info_t* info; /* thread-specific connection information */ int len; /* value-result argument to accept */ pthread_t thread_id; /* child thread identifier */ /* Signal a bug for invalid descriptors. */ ASSERT (fd > 0); /* Initialize the POSIX threads attribute structure. */ if (pthread_attr_init (&attr)!= 0) { fputs ("failed to initialize pthread attributes\n", stderr); return; } /* The main thread never joins with the children. */ if (pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED)!= 0) { fputs ("failed to set detached state attribute\n", stderr); return; } 10/11/06 UIUC - CS/ECE 438, Fall 2006 46

wait_for_connections /* Use an infinite loop to wait for connections. For each connection, create a structure with the thread-specific data, then spawn a child thread and pass it the data. The child is responsible for deallocating the memory before it terminates. */ while (1) { /* Create a thread information structure and initialize fields that can be filled in before a client contacts the server. */ if ((info = calloc (1, sizeof (*info))) == NULL) { perror ("wait_for_connections/calloc"); return; } info->fname = NULL; info->last_sent = (time_t)0; 10/11/06 UIUC - CS/ECE 438, Fall 2006 47

wait_for_connections } } /* Wait for a client to contact the server. */ len = sizeof (info->addr); if ((info->fd = accept (fd, (struct sockaddr*)&info->addr, &len)) == -1) { perror ("accept"); return; } /* Create a thread to handle the client. */ if (pthread_create (&thread_id, &attr, (void* (*) (void*))client_thread, info)!= 0) { fputs ("failed to create thread\n", stderr); } /* The child does not exist, the main thread must clean up. */ close (info->fd); free (info); return; 10/11/06 UIUC - CS/ECE 438, Fall 2006 48

client_thread void client_thread (thread_info_t* info) { /* Check argument. */ ASSERT (info!= NULL); } /* Free the thread info block whenever the thread terminates. Note that pushing this cleanup function races with external termination. If external termination wins, the memory is never released. */ pthread_cleanup_push ((void (*)(void*))release_thread_info, info); /* Loop between waiting for a request and sending a new copy of the current file of interest. */ while (read_client_request (info) == 0 && send_file_to_client (info) == 0); /* Defer cancellations to avoid re-entering deallocation routine (release_thread_info) in the middle, then pop (and execute) the deallocation routine.*/ pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL); pthread_cleanup_pop (1); 10/11/06 UIUC - CS/ECE 438, Fall 2006 49

client_has_data static int client_has_data (int fd) { fd_set read_set; struct timeval timeout; /* Check argument. */ ASSERT (fd > 0); /* Set timeout for select. */ timeout.tv_sec = CHECK_PERIOD; timeout.tv_usec = 0; /* Set read mask for select. */ FD_ZERO (&read_set); FD_SET (fd, &read_set); /* Call select. Possible return values are {-1, 0, 1}. */ if (select (fd + 1, &read_set, NULL, NULL, &timeout) < 1) { /* We can't check errno in a thread--assume nothing bad has happened. */ return 0; } /* Select returned 1 file descriptor ready for reading. */ return 1; } 10/11/06 UIUC - CS/ECE 438, Fall 2006 50