210 likes | 307 Views
Communication Networks. Recitation 2. TCP/IP Socket Programming Cont. Outline. Send/Receive data Terminating a connection Dealing with blocking calls Client-server model summary. Sending / Receiving Data. With a connection (SOCK_STREAM): int count = send(sock, &buf, len, flags);
E N D
Communication Networks Recitation 2 Comnet 2006 - Recitation 2 - Sockets
TCP/IP Socket ProgrammingCont. Comnet 2006 - Recitation 2 - Sockets
Outline Send/Receive data Terminating a connection Dealing with blocking calls Client-server model summary Comnet 2006 - Recitation 2 - Sockets
Sending / Receiving Data • With a connection (SOCK_STREAM): • int count = send(sock, &buf, len, flags); • count: # bytes transmitted (-1 if error) • buf: char[], buffer to be transmitted • len: integer, length of buffer (in bytes) to transmit • flags: integer, special options, usually just 0 • int count = recv(sock, &buf, len, flags); • count: # bytes received (-1 if error) • buf: void[], stores received bytes • len: max # bytes received • flags: integer, special options, usually just 0 Comnet 2006 - Recitation 2 - Sockets
Example of send() … connect(sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)); … char *msg = "Comnet is the course!"; int len, bytes_sent; len = strlen(msg); bytes_sent = send(sock, msg, len, 0); Comnet 2006 - Recitation 2 - Sockets
Sending / Receiving Data (cont’d) • Without a connection (SOCK_DGRAM): • int count = sendto(sock, &buf, len, flags, &addr, addrlen); • count, sock, buf, len, flags: same as send • addr: struct sockaddr, address of the destination • addrlen: sizeof(addr) • int count = recvfrom(sock, &buf, len, flags, &addr, &addrlen); • count, sock, buf, len, flags: same as recv • name: struct sockaddr, address of the source • namelen: sizeof(name): value/result parameter Comnet 2006 - Recitation 2 - Sockets
Sending/Receiving notes • send( ) might send only a fraction of the buffer • Need to push the rest • See sendall( ) in Beej’s guide • recv( ) might get several messages together, or a fraction of a message • Need to be able to identify message’s beginning and end Comnet 2006 - Recitation 2 - Sockets
Closing connection • When finished using a socket, the socket should be closed: • status = close(s); • status: 0 if successful, -1 if error • s: the file descriptor (socket being closed) • Closing a socket • closes a connection (for SOCK_STREAM) • frees up the port used by the socket Comnet 2006 - Recitation 2 - Sockets
Skipping the bind() • SOCK_DGRAM: • if only sending, no need to bind. The OS finds a port each time the socket sends a packet • if receiving, need to bind • SOCK_STREAM: • The OS binds a port to the client during connection setup Comnet 2006 - Recitation 2 - Sockets
Dealing with blocking calls • Many of the functions we saw block until a certain event • accept: until a connection comes in • connect: until the connection is established • recv, recvfrom: until a packet (of data) is received • send, sendto: until data is pushed into socket’s buffer • For simple programs, blocking is convenient • What about more complex programs? • multiple connections • simultaneous sends and receives • simultaneously doing non-networking processing Comnet 2006 - Recitation 2 - Sockets
Dealing with blocking (cont’d) • Options: • create multi-process or multi-threaded code • turn off the blocking feature using the fcntl() file-descriptor control function • use the select() function call. Comnet 2006 - Recitation 2 - Sockets
fcntl() function call • int fcntl(int filedes, int cmd, args ...); • status: -1 if error • filedes: argument is an open file descriptor • cmd: specifies the operation to be performed • arg: depends upon the value of cmd sockfd = socket(PF_INET, SOCK_STREAM, 0); fcntl(sockfd, F_SETFL, O_NONBLOCK); Comnet 2006 - Recitation 2 - Sockets
Using select() • What does select do? • can be permanent blocking, time-limited blocking or non-blocking • input: a set of file-descriptors • output: info on the file-descriptors’ status • i.e., can identify sockets that are “ready for use”: calls involving that socket will return immediately Comnet 2006 - Recitation 2 - Sockets
select() function call • int status = select(nfds, &readfds, &writefds, &exceptfds, &timeout); • status: # of ready objects, -1 if error • nfds: 1 + largest file descriptor to check • readfds: set of descriptors to check if read-ready • writefds: set of descriptors to check if write-ready • exceptfds: set of descriptors to check if an exception is registered • timeout: time after which select returns, even if nothing ready - can be 0 or Comnet 2006 - Recitation 2 - Sockets
To be used with select(): • For sets, select uses a structure, struct fd_set • it is just a bit-vector • if bit i is set in [readfds, writefds, exceptfds], select will check if file descriptor (i.e. socket) i is ready for [reading, writing, exception] • Before calling select: • FD_ZERO(&fdvar): clears the structure • FD_SET(i, &fdvar): to check file desc. i • After calling select: • int FD_ISSET(i, &fdvar): boolean returns TRUE iff i is “ready to read” • Standard input (STDIN) is file descriptor 0 Comnet 2006 - Recitation 2 - Sockets
Timeout parameter struct timeval { int tv_sec; // seconds int tv_usec; // microseconds }; • Set timeout to NULL for no timeout • Set both to 0 for immediate timeout Comnet 2006 - Recitation 2 - Sockets
Ready to read • Listening port is read-ready if accept won’t block • Closed connections are read-ready but recv( ) returns 0 bytes Comnet 2006 - Recitation 2 - Sockets
Other useful functions • bzero(char* c, int n): 0’s n bytes starting at c • gethostname(char *name, int len): gets the name of the current host • gethostbyname(const char *name): converts host’s name to structure containing long integer char hostname[128]; struct hostent *he; gethostname( hostname, sizeof( hostname) ); printf( “My hostname:%s\n”, hostname ); he = gethostbyname( “www.yahoo.com” ); printf( “Address: %s\n”, inet_n_ntoa( he->h_addr ) ); Comnet 2006 - Recitation 2 - Sockets
Useful functions (cont.) • gethostbyaddr(char *addr, int len, int type): converts IP hostname to structure containing long integer • inet_aton(const char *cp, struct in_addr *inp): converts dotted-decimal char-string to binary (network order) • inet_ntoa(const struct in_addr in): converts binary to dotted-decimal string struct hostent *he; struct in_addr addr; inet_aton( “66.94.230.32”, &addr ); printf( “Address: %s\n”, inet_ntoa( addr.sin_addr ) ); he = gethostbyaddr( &addr, sizeof( addr ), AF_INET ); printf( “Name: %s\n”, he->h_name ); Comnet 2006 - Recitation 2 - Sockets
UDP Client-Server UDP Server socket() UDP Client socket() bind() bind() recvfrom() blocks data (request) sendto() process request data (reply) sendto() recvfrom() close() close() Comnet 2006 - Recitation 2 - Sockets
TCP Client-Server TCP Server socket() bind() TCP Client listen() socket() connection establishment 3-way handshake accept() connect() blocks until connection from client write() data (request) read() process request data (reply) read() write() end-of-file notification close() read() Comnet 2006 - Recitation 2 - Sockets close()