1 / 31

Review of Previous Lecture

Review of Previous Lecture. Electronic Mail: SMTP, POP3, IMAP DNS Socket programming with TCP. Announcement. Homework 1 and project 1 due Wed. midnight Recitation materials online. Outline. Socket programming with TCP Socket programming with UDP I/O multiplexing Web caching. TCP Server.

ryles
Télécharger la présentation

Review of Previous Lecture

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Review of Previous Lecture • Electronic Mail: SMTP, POP3, IMAP • DNS • Socket programming with TCP Some slides are in courtesy of J. Kurose and K. Ross

  2. Announcement • Homework 1 and project 1 due Wed. midnight • Recitation materials online

  3. Outline • Socket programming with TCP • Socket programming with UDP • I/O multiplexing • Web caching

  4. TCP Server socket() bind() Well-known port TCP Client listen() Socket() accept() blocks until connection from client connect() Connection establishment Data(request) write() read() process request Data(reply) write() read() close() End-of-file notification read() close()

  5. Ipv4 socket address structure struct socketaddr_in{ uint8_t sin_len; /*length of the structure (16)*/ sa_falimily_t sin_family /* AF_INT*/ in_port_t sin_port /* 16 bit TCP or UDP port number*/ struct in_addr sin_addr /* 32 bit Ipv4 address */ char sin_zero(8)/* unused*/ } Hostent structure struct hostent{ char * h_name /*official name of host*/ char ** h_aliases; /* pointer ot array of\ pointers to alias name*/ int h_addrtype /* host address type*/ int h_length /* length of address */ char ** h_addr_list /*prt to array of ptrs with \ IPv4 or IPv6 address*/ } Make the socket Socket(int family , int type, in t protocol); return nonnegative value for OK, -1 for error Resolve the host struct hostent *gethostbyname( const char *hostname); /*Return nonnull pointer if OK, NULL on error */ unit16_t htons(unit16_t host16bitvaule) /*Change the port number from host byte order to network byte order */ connect(int socketfd, const struct sockaddr * servaddr, socket_t addrlen) /*Perform the TCP three way handshaking*/ Setup up the struct Connect int connect_ socket( char *hostname, int port) { int sock; struct sockaddr_in sin; struct hostent *host; sock = socket( AF_ INET, SOCK_ STREAM, 0); if (sock == -1) return sock; host = gethostbyname( hostname); if (host == NULL) { close( sock); return -1; } memset (& sin, 0, sizeof( sin)); sin. sin_ family = AF_ INET; sin. sin_ port = htons( port); sin. sin_ addr. s_ addr = *( unsigned long *) host-> h_ addr_ list[ 0]; if (connect( sock, (struct sockaddr *) &sin, sizeof( sin)) != 0) { close (sock); return -1; } return sock; }

  6. Server – high level view Create a socket Bind the socket Listen for connections Accept new client connections Read/write to client connections Shutdown connection

  7. Assigning an address to a socket • The bind() system call is used to assign an address to an existing socket. int bind( int sockfd, const struct sockaddr *myaddr, int addrlen); • bind returns 0 if successful or -1 on error.

  8. bind() • calling bind()assigns the address specified by the sockaddr structure to the socket descriptor. • You can give bind()a sockaddr_instructure: bind( mysock, (struct sockaddr*) &myaddr, sizeof(myaddr) );

  9. bind() Example int mysock,err; struct sockaddr_in myaddr; mysock = socket(PF_INET,SOCK_STREAM,0); myaddr.sin_family = AF_INET; myaddr.sin_port = htons( portnum ); myaddr.sin_addr = htonl( ipaddress); err=bind(mysock, (sockaddr *) &myaddr, sizeof(myaddr));

  10. Make the socket Setup up the struct Bind bind(int sockfd, const struct sockaddr * myaddr, socklen_t addrlen); /* return 0 if OK, -1 on error assigns a local protocol adress to a socket*/ Make listen socket (TCP) int make_ listen_ socket( int port) { struct sockaddr_ in sin; int sock; sock = socket( AF_ INET, SOCK_ STREAM, 0); if (sock < 0) return -1; memset(& sin, 0, sizeof( sin)); sin. sin_ family = AF_ INET; sin. sin_ addr. s_ addr = htonl( INADDR_ ANY); sin. sin_ port = htons( port); if (bind( sock, (struct sockaddr *) &sin, sizeof( sin)) < 0) return -1; return sock; }

  11. listen() int listen( int sockfd, int backlog); sockfd is the TCP socket (already bound to an address) backlog is the number of incoming connections the kernel should be able to keep track of (queue for us). listen() returns -1 on error (otherwise 0).

  12. Accepting an incoming connection. • Once we call listen(), the O.S. will queue incoming connections • Handles the 3-way handshake • Queues up multiple connections. • When our application is ready to handle a new connection, we need to ask the O.S. for the next connection.

  13. accept() int accept( int sockfd, struct sockaddr* cliaddr, socklen_t *addrlen); sockfd is the passive mode TCP socket. cliaddr is a pointer to allocated space. addrlen is a value-result argument • must be set to the size of cliaddr • on return, will be set to be the number of used bytes in cliaddr.

  14. accept() return value accept() returns a new socket descriptor (small positive integer) or -1 on error. After accept returns a new socket descriptor, I/O can be done using the read() and write() system calls. read() and write() operate a little differently on sockets (vs. file operation)!

  15. Setup up the struct Accept the client connection accept(int sockefd, struct sockaddr * claddr, socklen_t * addrlen) /* return nonnegative descriptor if OK, -1 on error return the next completed connection from the front of the completed connection queue. if the queue is empty, the process is put to sleep(assuming blocking socket)*/ Accepting a client connection (TCP) int get_ client_ socket( int listen_ socket) { struct sockaddr_ in sin; int sock; int sin_ len; memset(& sin, 0, sizeof( sin)); sin_ len = sizeof( sin); sock = accept( listen_ socket, (struct sockaddr *) &sin, &sin_ len); return sock; }

  16. Reading from/writing to a TCP socket int read( int fd, char *buf, int max); int write( int fd, char *buf, int num); • By default read() will block until data is available. • reading from a TCP socket may return less than max bytes (whatever is available). • You must be prepared to read data 1 byte at a time! • write might not be able to write all num bytes (on a nonblocking socket).

  17. Terminating a TCP 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

  18. TCP Server socket() bind() Well-known port TCP Client listen() Socket() accept() blocks until connection from client connect() Connection establishment Data(request) write() read() process request Data(reply) write() read() close() End-of-file notification read() close()

  19. Outline • Socket programming with TCP • Socket programming with UDP • I/O multiplexing • Web caching

  20. UDP: no “connection” between client and server no handshaking sender explicitly attaches IP address and port of destination to each packet server must extract IP address, port of sender from received packet UDP: transmitted data may be received out of order, or lost UDP provides unreliable transfer of groups of bytes (“datagrams”) between client and server application viewpoint Socket programming with UDP

  21. UDP Server socket() bind() Well-known port UDP Client recvfrom() Socket() blocks until datagram received from client Data(request) sendto() process request Data(reply) sendto() recvfrom() close()

  22. sendto() int sendto(int sock, const void *buf, int count, unsigned int flags, struct sockaddr *to_addr, int to_addrlen); • sock: socket descriptor previously created • buf: pointer to data to be transmitted • count: number of bytes to be transmitted • to_addr: filled with destination address and port number • to_addrlen: sizeof(to_addr) • Flags is generally set to 0 • Returns the number of bytes sent on success, otherwise errno is set and -1 returned • Only local errors are detected, and nothing can be said about whether the data actually reaches the other side

  23. recvfrom() int recvfrom(int sock, const void *buf, int count, unsigned int flags, struct sockaddr *from_addr, int *from_addrlen); • sock: socket descriptor previously created • buf: pointer to memory where data is to be stored • count: max number of bytes to be received (i.e., size of buf). • Flags is generally set to 0 • from_addr: filled with source address and port number. • Returns the number of bytes received on success, otherwise errno is set and -1 returned.

  24. Caveats about recvfrom() • If no data is available, recvfrom() will block indefinitely until a message arrives • If buf is not long enough to contain the data, the message may be truncated

  25. Outline • Socket programming with TCP • Socket programming with UDP • I/O multiplexing

  26. Dealing with blocking calls • Many functions block • accept(), connect(), recvfrom() • For simple programs this is fine • What about complex connection routines • Multiple connections • Simultaneous sends and receives • Simultaneously doing non-networking processing

  27. How to handle multiple connections • Create multi-process or multi-threaded code • More complex, requires mutex, semaphores, etc. • Not covered • I/O multiplexing using polling • Turn off blocking feature (fcntl() system call) • Very inefficient • I/O multiplexing using select ()

  28. I/O Multiplexing: Polling int opts = fcntl (sock, F_GETFL); if (opts < 0) { perror ("fcntl(F_GETFL)"); abort (); } opts = (opts | O_NONBLOCK); if (fcntl (sock, F_SETFL, opts) < 0) { perror ("fcntl(F_SETFL)"); abort (); } while (1) { if (receive_packets(buffer, buffer_len, &bytes_read) != 0) { break; } if (read_user(user_buffer, user_buffer_len, &user_bytes_read) != 0) { break; } } first get current socket option settings then adjust settings finally store settings back get data from socket get user input

  29. I/O Multiplexing: Select (1) • Select() • Wait on multiple file descriptors/sockets and timeout • Return when any file descriptor • is ready to be read or written, or • Indicate an error, or • timeout exceeded • Advantages • Simple • Application does not consume CPU cycles while waiting

  30. I/O Multiplexing: Select (2) set up parameters for select() fd_set read_set; struct timeval time_out; while (1) { FD_ZERO (read_set); FD_SET (stdin, read_set); /* stdin is typically 0 */ FD_SET (sock, read_set); time_out.tv_usec = 100000; time_out.tv_sec = 0; select_retval = select(MAX(stdin, sock) + 1, &read_set, NULL, NULL, &time_out); if (select_retval < 0) { perror ("select"); abort (); } if (select_retval > 0) { if (FD_ISSET(sock, read_set)) { if (receive_packets(buffer, buffer_len, &bytes_read) != 0) { break; } if (FD_ISSET(stdin, read_set)) { if (read_user(user_buffer, user_buffer_len, &user_bytes_read) != 0) { break; } } } } run select() interpret result

  31. select function call • int status = select() • Status: # of ready objects, -1 if error • nfds: 1 +largest file descriptor to check • readfds: list of descriptors to check if read-ready • writefds: list of descriptors to check if write-ready • exceptfds: list of descriptors to check if an exception is registered • Timeout: time after which select returns

More Related