500 likes | 628 Views
CSE 30264 Computer Networks. Prof. Aaron Striegel Department of Computer Science & Engineering University of Notre Dame Lecture 3 – January 14, 2010. Implementing Network Software. Outline Sockets Example Homework 2. Communication Paradigms. Stream Paradigm (TCP). Stream
E N D
CSE 30264Computer Networks Prof. Aaron Striegel Department of Computer Science & Engineering University of Notre Dame Lecture 3 – January 14, 2010
Implementing Network Software Outline Sockets Example Homework 2 CSE 30264
Communication Paradigms CSE 30264
Stream Paradigm (TCP) • Stream • Sequenceof bytes flows from oneapplication program to another • Think of it like a tube of data • Bi-directional • Streams in both directions • Client to server, server to client • No boundaries • Streaming protocol does not understand boundaries • Stream of bits • No size limits* • One byte -> large blocks of data • * From the application perspective • Protocol selects delivery size • Combine smaller blocks • Divide large blocks IIS firefox Port: 80 Port: 7583 129.74.120.75 129.74.200.5 firefox IIS 129.74.120.75, 80 129.74.200.5, 7583 CSE 30264
Message Paradigm (UDP) • Message paradigm • Network accepts and delivers messages • Datagram service • Messages are self-contained • Protocol simply forwards • No re-assembly, highly aware of packetization • N bytes in a message, N bytesreceived on the other side • Size limit on messages • May be uni-directional or bi-directional • Spray and pray – no guarantees • May be lost • Delivered out-of-order • May be duplicated • More burden on programmer Port: 8000 Port: 42083 firefox Shoutcast 62.74.89.71 129.74.200.10 Shoutcast Destination129.74.200.10,42083 CSE 30264
Sockets OperatingSystem • Socket programming • Adapter that gets an apponto the network • API – Application Programming Interface • Give me a TCP socket, hold the aggregation Network Stack Socket DeviceDrivers PhysicalAdapter CSE 30264
Socket Operations • Dependent on type of socket • Different ops for TCP vs. UDP • Supported operations • Specify local/remote communication endpoints • Who / where -> IP address / port • Initiate a connection • Ring the telephone • Wait for a connection • Server • Send/receive data • Handle incoming data • Terminate connection gracefully • Handle connection termination from remote site • Abort communication • Handle error conditions or connection abort • Allocate and release local resources Not to be confused with Sprockets CSE 30264
Socket Communication • Very similar to file I/O • File I/O • Open, close, read, write, seek, fcntl, ... • Network communication • File descriptor for network comms • Socket is just another file handle • Is a network connection really a file? • Initiate, respond to aborted connection • Socket API was born • Nominally the same between C and C++ • Similar beyond C, C++ • Java, Perl, PHP, C# CSE 30264
Upcoming Programming • Homework 2 - Implement a UDP client • Connect to a server • Send a message • Receive a message • Project 1 – Implement Client / Server • Small scale TCP • Google is your friend • Just document where you get help from • C UDP Socket Tutorial http://www.cs.ucsb.edu/~almeroth/classes/W01.176B/hw2/examples/udp-client.c CSE 30264
Refresh -> Client-Server Model • Server listens for requests from clients • Server: passive open • Client: active open • Example: • file server • web server • print server • mail server • name server • X window server request response SERVER CLIENTS CSE 30264
Overview - TCP SERVER socket() bind() CLIENT listen() socket() accept() blocks until connection from client connect() connection establishment data request read() write() process request data reply write() read() CSE 30264
Overview - UDP SERVER socket() CLIENT socket() sendto() recvfrom() data recvfrom() data sendto() CSE 30264
Socket Creation intsocket(int family,inttype,intprotocol); • Return value: • Socket descriptor • Use for all subsequent operations CSE 30264
Socket Creation #include <sys/types.h> #include <sys/socket.h> ints; s= socket (PF_INET, SOCK_STREAM, 0); Default Protocol Family – Internet Socket Type – Streaming Socket CSE 30264
Socket Creation • Family • PF_INET, PF_UNIX, ... • Also may be listed as AF_INET (Address Family) • Socket Types • Datagram UDP SOCK_DGRAM • Reliable stream TCP SOCK_STREAM • Raw IP SOCK_RAW • Must be root to use • Protocol • Typically 0 = default protocol for type CSE 30264
Endpoint Addresses • Different protocols may have different representations. • TCP/IP uses combination of IP address and port. • Sockets offer different ‘address families’ • TCP/IP uses a single address representation (AF_INET). • PF_INET, AF_INET often confused • Use same numeric value. • Most code#define PF_INET AF_INET (Linux) Bind for the local one Two addresses Connect to the remote one CSE 30264
Socket Addresses structsockaddr { /* sys/socket.h */ sa_family_tsa_family; /* address family */ char sa_data[14]; /* addressing information */ } structsockaddr_in { short sin_family; /* AF_INET */ u_shortsin_port; /* network byte order */ structsin_addrsin_addr; /* network address */ } (1) (2) Two options (1) is most common, (2) is actually the recommended approach CSE 30264
Refresher - C • Types – char, short, long • Pointers • size • struct • typecasting • Memset • Endian-ness See board in class / wiki for more examples CSE 30264
Binding the Local Address intbind(ints, structsockaddr *addr,intaddresslen); • Socket has no notion of endpoint addresses when created • Neither local nor remote • Necessary on the server side • Need to specify the local endpoint • Not always necessary for the client • May just need to send data towards a destination • Let OS auto-assign CSE 30264
Binding the Local Address #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> ints; structsockaddr_in sin; s = socket(PF_INET, SOCK_DGRAM, 0); memset((char *)&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons (6000); /* 0 -> let system choose */ sin.sin_addr.s_addr = htonl(INADDR_ANY); /* allow any interface */ bind (s, (structsockaddr *)&sin, sizeof(sin)); CSE 30264
Breaking the Code Down memset((char *)&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons (6000); /* 0 -> let system choose */ sin.sin_addr.s_addr = htonl(INADDR_ANY); /* allow any interface */ Take the struct and initialize it to zeroes memset((char *)&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons (6000); /* 0 -> let system choose */ sin.sin_addr.s_addr = htonl(INADDR_ANY); /* allow any interface */ Set the address family to Internet CSE 30264
Breaking the Code Down memset((char *)&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons (6000); sin.sin_addr.s_addr = htonl(INADDR_ANY); htons – Host to network short The port should be set to 6000 htonl – Host to network long memset((char *)&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons (6000); sin.sin_addr.s_addr = htonl(INADDR_ANY); Just use a local address, I don’t care which one CSE 30264
Converting a String • What if we need to specify an address? • inet_addr(char *) • Takes a string with the dot notation, converts to a four byte IPv4 value inet_addr(“129.74.56.5”) inet_addr(argv[1]) CSE 30264
Breaking the Code Down • bind (s, (structsockaddr *)&sin, sizeof(sin)); Bind our socket s to the information in the socket address structure sin and oh by the way, here is the size of that struct too Typecast – oh yeah! CSE 30264
netstat • HW 1 • netstat –ra • Routing table • Shows socket usage CSE 30264
setsockopt()/getsockopt() • May need to tweak the socket • How long to wait to purge a socket? • Default is two MSL (Maximum Segment Lengths) • If not properly terminated, bind() will return EADDRINUSE. setsockopt(ints, int level, intoptname, const void *optval, intoptlen); getsockopt(ints, int level, intoptname, void *optval, int *optlen); • Before bind:setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); • Allows re-use of port in use. CSE 30264
Why reuse ports? • What if your code crashes? • Otherwise, you wait … wait … wait … wait • When we write servers, you will get a range of ports to use • Rogue programs • ps –A –fkill XXXX (XXXX is PID) CSE 30264
What do we have so far? • socket() • Creates the local “handle” • Identifier for all socket operations • bind() • Allows us to pick the endpoint address • Port number • Potentially address on a multi-interface machine • Must be done on the server • setsocketopt, getsocketopt • Change socket options CSE 30264
Contrast – TCP, UDP SERVER TCP Only socket() TCP, UDP bind() CLIENT listen() socket() accept() blocks until connection from client connect() connection establishment data request write(), sendto() read() Technically, it is possibleto use connectwith UDP process request data reply write() read(), recvfrom() CSE 30264
Overview - UDP SERVER socket() CLIENT socket() sendto() recvfrom() data recvfrom() data sendto() CSE 30264
connect() intconnect(ints,structsockaddr *addr,intnamelen); • Client issues connect() to • Establish remote address and port • Establish connection • Fails if host not listening to port CSE 30264
Class Exercise • Sketch the code for a connect call to the following location: IP Address: 192.168.4.6 Port: 89 CSE 30264
UDP – Send / Receive Data • UDP -> Spray and Pray • sendto -> Send a message • recvfrom -> Listen on the port for a message • Key parameters • Socket • Buffer pointer • Buffer size (bytes) • Socket address • Size of socket address struct CSE 30264
recvfrom ssize_trecvfrom(int socket, void *buffer,size_tlength,intflags, structsockaddr *address,socklen_t*address_len); Socket Pointer to a pre-allocated buffer Size of the buffer (to avoid overflow) Flags (usually 0) Address struct – where the packet came from Length of the address May be NULL CSE 30264
sendto ssize_tsendto(int socket, const void *message,size_tlength,intflags, const structsockaddr *dest_addr,socklen_tdest_len); Socket Pointer to a pre-allocated buffer Size of the buffer (to avoid overflow) Flags (usually 0) Address struct – where the packet came from Length of the address CSE 30264
In-Class Derivation • Write a small snippet of code to send a packet via UDP CSE 30264
Where next? • UDP – protocol is up to programmer • How many messages? • Who talks when? • What type of message? Homework 2: Write a simple UDP client Read a small text file Send to the server Read / display the response CSE 30264
Revisiting TCP – Server Side SERVER TCP Only socket() TCP, UDP bind() CLIENT listen() socket() accept() blocks until connection from client connect() connection establishment data request write(), sendto() read() process request data reply write() read(), recvfrom() CSE 30264
listen() intlisten(ints, int backlog); • Only for stream sockets. • Socket being listened to can’t be used for client. • listen() does not wait for connections, but needed to receive connection attempts. • Completes 3-way handshake. CSE 30264
listen() • Allows backlog pending connection requests (SYN, completed 3WH) while waiting for accept(). • Queue full: SYN requests are silently dropped. • “SYN-flood”: send fake TCP SYN requests to fill queue. CSE 30264
TCP Preview client server port=64444 port=9 active open connect() SYN j (64444, 9) listen() SYN k ACK j+1 (9, 64444) ACK k+1 (64444, 9) active close close() FIN ACK CSE 30264
accept() intaccept(ints, structsockaddr *addr,int*addrlen); • By connection-oriented server, after listen(). • Can’t preview connection: accept and close. • Returns a new socket. • Returns address of client. CSE 30264
Sending/Receiving • TCP • read/write: send/receive, no explicit address • send/recv: send/receive, flags • UDP • sendto: specify destination explicitly • recvfrom: also receive address of peer • sendmsg: msghdr data structure, scatter/gather • recvmsg: msghdr data structure, scatter/gather CSE 30264
Example: TCP Client #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> int main(int argc, char *argv[]) { int s, n; struct sockaddr_in sin; char msg[80] = “Hello, World!”; if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror(“socket”); return(-1); } CSE 30264
Example: TCP Client sin.sin_family = AF_INET; sin.sin_port = htons(atoi(argv[2])); sin_addr.s_addr = inet_addr(argv[1]); if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { perror(“connect”); return -1; } if (write(s, msg, strlen(msg)+1) < 0) { perror(“write”); return -1; } if ((n = read(s, msg, sizeof(msg))) < 0) { perror(“read”); return -1; } printf(“%d bytes: %s\n”, n, msg); if (close(s) < 0) { perror(“close”); return -1; } return 0; } CSE 30264
Single-Threaded Server int server; server = initialize(); while (1) { wait_for_request(server); read_request; send_answer; } CSE 30264
Example: TCP Server int main(int argc, char *argv[]) { int s, t, n; struct sockaddr_in sin; char *r; char buf[100]; int sinlen; if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror(“socket); return -1; } sin.sin_family = AF_INET; sin.sin_port = htons(13333); sin.sin_addr.s_addr = INADDR_ANY; if (bind (s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { perror(“bind”); return -1; } if (listen(s, 5) < 0) { perror(“listen”); return -1;} CSE 30264
Example: TCP Server for (;;) { sinlen = sizeof(sin); if ((t = accept(s, (struct sockaddr *) &sin, &sinlen)) < 0) { perror(“accept”); return -1; } if (read(t, &buf, 100) < 0) { perror (“read”); return -1;} r = gettime(); if (write(t, r, strlen(r)) < 0) { perror (“write”); return -1; } if (close(t) < 0) { perror(“close”); return -1; } } if (close(s) < 0) { perror(“close”); return -1; } } CSE 30264
Other Socket Functions • The socket API contains a variety of support functions • getpeername • gethostname • setsockopt • getsockopt • gethostbyname • gethostbyaddr CSE 30264
What About Threaded Servers? • The socket API works well with concurrent servers • Implementations of the socket API adhere to the following inheritance principle: • each new thread that is created inherits a copy of all open sockets from the thread that created it • the socket implementation uses a reference count mechanism to control each socket • when a socket is first created • the system sets the socket’s reference count to 1 • and the socket exists as long as the reference count remains positive. • when a program creates an additional thread • the thread inherits a pointer to each open socket the program owns • and the system increments the reference count of each socket by 1 • when a thread calls close • the system decrements the reference count for the socket • if the reference count has reached zero, the socket is removed CSE 30264