Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 11 Overview.

Similar presentations


Presentation on theme: "Lecture 11 Overview."— Presentation transcript:

1 Lecture 11 Overview

2 Creating a TCP socket int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen); int mysock; struct sockaddr_in myaddr; mysock = socket(PF_INET,SOCK_STREAM,0); myaddr.sin_family = AF_INET; myaddr.sin_port = htons( 80 ); myaddr.sin_addr = htonl( INADDR_ANY ); bind(mysock, (sockaddr *) &myaddr, sizeof(myaddr)); CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

3 Establishing a passive mode TCP socket
Address already determined Tell the kernel to accept incoming connection requests directed at the socket address 3-way handshake Tell the kernel to queue incoming connections for us CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

4 listen() sockfd is the TCP socket
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) Sum of incomplete and completed queues CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

5 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 CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

6 accept() sockfd is the passive mode TCP socket
int accept( int sockfd, struct sockaddr* cliaddr, socklen_t *addrlen); sockfd is the passive mode TCP socket initiated by socket(), bind(), and listen() 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 CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

7 Terminating a TCP connection
int close(int sockfd); Either end of the connection can call the close() system call What if there is data being sent? If the other end has closed the connection, and there is no buffered data, reading from a TCP socket returns 0 to indicate EOF. CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

8 Client Code TCP clients can call connect() which:
takes care of establishing an endpoint address for the client socket Attempts to establish a connection to the specified server 3-way handshake no need to call bind first, the O.S. will take care of assigning the local endpoint address TCP port number, IP address CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

9 connect() sockfd is an already created TCP socket
int connect( int sockfd, const struct sockaddr *server, socklen_t addrlen); sockfd is an already created TCP socket server contains the address of the server connect() returns 0 if OK, -1 on error No response to SYN segment (3 trials) RST signal ICMP destination unreachable (3 trials) CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

10 Reading from a TCP socket
int read(int fd, char *buf, int max); 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! CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

11 Writing to a TCP socket int write(int fd, char *buf, int num); write might not be able to write all num bytes on a nonblocking socket readn(), writen() and readline() functions CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

12 Creating a UDP socket int mysock; struct sockaddr_in myaddr; Mysock=socket(PF_INET,SOCK_DGRAM,0); myaddr.sin_family = AF_INET; myaddr.sin_port = htons(1234); myaddr.sin_addr = htonl(INADDR_ANY); bind(mysock, &myaddr, sizeof(myaddr)); CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

13 Sending UDP Datagrams sockfd is a UDP socket
ssize_t sendto( int sockfd, void *buff, size_t nbytes, int flags, const struct sockaddr* to, socklen_t addrlen); sockfd is a UDP socket buff is the address of the data (nbytes long) to is the destination address Return value is the number of bytes sent, or -1 on error. CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

14 sendto() The return value of sendto() indicates how much data was accepted by the O.S. for sending as a datagram not how much data made it to the destination. There is no error condition that indicates that the destination did not get the data!!! You can send 0 bytes of data! CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

15 Receiving UDP Datagrams
ssize_t recvfrom( int sockfd, void *buff, size_t nbytes, int flags, struct sockaddr* from, socklen_t *fromaddrlen); sockfd is a UDP socket buff is the address of a buffer (nbytes long) from is the address of a sockaddr Return value is the number of bytes received and put into buff, or -1 on error CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

16 recvfrom() If buff is not large enough, any extra data is lost forever... You can receive 0 bytes of data! recvfrom doesn’t return until there is a datagram available, You should set fromaddrlen before calling If from and fromaddrlen are NULL we don’t find out who sent the data CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

17 Typical UDP Communication
CPE 401/601 Lecture 11 : TCP & UDP Socket Programming

18 Lecture 12 Socket Programming Issues
CPE 401 / 601 Computer Network Systems slides are modified from Dave Hollinger slides are modified from Dave Hollinger

19 Debugging Debugging can be difficult
Write routines to print out sockaddrs Use trace, strace, ptrace, truss, etc Include code that can handle unexpected situations CPE 401/601 Lecture 12 : Socket Programming Issues

20 Timeout when calling recvfrom()
It might be nice to have each call to recvfrom() return after a specified period of time even if there is no incoming datagram We can do this by using SIGALRM and wrapping each call to recvfrom() with a call to alarm() There are some other (better) ways to do this CPE 401/601 Lecture 12 : Socket Programming Issues

21 UDP Connected mode A UDP socket can be used in a call to connect()
This simply tells the O.S. the address of the peer No handshake is made to establish that the peer exists No data of any kind is sent on the network as a result of calling connect() on a UDP socket CPE 401/601 Lecture 12 : Socket Programming Issues

22 Connected UDP Once a UDP socket is connected:
can use sendto() with a null dest address can use write() and send() can use read() and recv() only datagrams from the peer will be returned Asynchronous errors will be returned to the process OS Specific, some won’t do this! CPE 401/601 Lecture 12 : Socket Programming Issues

23 Asynchronous Errors What happens if a client sends data to a server that is not running? ICMP “port unreachable” error is generated by receiving host and sent to sending host The ICMP error may reach the sending host after sendto() has already returned! The next call dealing with the socket could return the error CPE 401/601 Lecture 12 : Socket Programming Issues

24 Back to UDP connect() Connect() is typically used with UDP when communication is with a single peer only It is possible to disconnect and connect the same socket to a new peer More efficient to send multiple datagrams to the same user Many UDP clients use connect() Some servers (TFTP) CPE 401/601 Lecture 12 : Socket Programming Issues

25 I/O Multiplexing We often need to be able to monitor multiple descriptors: a generic TCP client (like telnet) a server that handles both TCP and UDP Client that can make multiple concurrent requests browser CPE 401/601 Lecture 12 : I/O Multiplexing

26 Example - generic TCP client
Input from standard input should be sent to a TCP socket Input from a TCP socket should be sent to standard output How do we know when to check for input from each source? STDIN STDOUT TCP SOCKET CPE 401/601 Lecture 12 : I/O Multiplexing

27 Options Use multiple processes/threads Use nonblocking I/O
use fcntl() to set O_NONBLOCK Use alarm and signal handler to interrupt slow system calls Use functions that support checking of multiple input sources at the same time CPE 401/601 Lecture 12 : I/O Multiplexing

28 Non blocking I/O Tell kernel not to block a process if I/O requests can not be completed use fcntl() to set O_NONBLOCK: int flags; flags = fcntl(sock,F_GETFL,0); fcntl(sock,F_SETFL,flags | O_NONBLOCK); Now calls to read() (and other system calls) will return an error and set errno to EWOULDBLOCK CPE 401/601 Lecture 12 : I/O Multiplexing

29 Non blocking I/O while (! done) { if ( (n=read(STDIN_FILENO,…)<0)) if (errno != EWOULDBLOCK) /* ERROR */ else write(tcpsock,…) if ( (n=read(tcpsock,…)<0)) else write(STDOUT_FILENO,…) } CPE 401/601 Lecture 12 : I/O Multiplexing

30 The problem with nonblocking I/O
Using blocking I/O allows the OS to put your process to sleep when nothing is happening Once input arrives, the OS will wake up your process and read() (or whatever) will return With nonblocking I/O, the process will chew up all available processor time!!! CPE 401/601 Lecture 12 : I/O Multiplexing

31 Using alarms signal(SIGALRM, sig_alrm); alarm(MAX_TIME); read(STDIN_FILENO,…); ... read(tcpsock,…); A function you write CPE 401/601 Lecture 12 : I/O Multiplexing

32 “Alarming” Issues What will happen to the response time ?
What is the ‘right’ value for MAX_TIME? CPE 401/601 Lecture 12 : I/O Multiplexing

33 Select() The select() system call allows us to use blocking I/O on a set of descriptors file, socket, … We can ask select to notify us when data is available for reading on either STDIN or a socket CPE 401/601 Lecture 12 : I/O Multiplexing

34 select() maxfd: highest number assigned to a descriptor
int select( int maxfd, fd_set *readset, fd_set *writeset, fd_set *excepset, const struct timeval *timeout); maxfd: highest number assigned to a descriptor readset: set of descriptors we want to read from writeset: set of descriptors we want to write to excepset: set of descriptors to watch for exceptions timeout: maximum time select should wait CPE 401/601 Lecture 12 : I/O Multiplexing

35 struct timeval To return immediately after checking descriptors
long tv_sec; /* seconds */ long tv_usec; /* microseconds */ } struct timeval max = {1,0}; To return immediately after checking descriptors set timeout as {0, 0} To wait until I/O is ready set timeout as a NULL pointer CPE 401/601 Lecture 12 : I/O Multiplexing

36 fd_set Operations you can use with an fd_set: Clear all bits in fd_set
void FD_ZERO(fd_set *fdset); Turn on the bit for fd in fd_set void FD_SET(int fd, fd_set *fdset); Turn off the bit for fd in fd_set void FD_CLR(int fd, fd_set *fdset); Check whether the bit for fd in fd_set is on int FD_ISSET(int fd, fd_set *fdset); CPE 401/601 Lecture 12 : I/O Multiplexing

37 Using select() Create fd_set Clear the whole thing with FD_ZERO
Add each descriptor you want to watch using FD_SET Call select when select returns, use FD_ISSET to see if I/O is possible on each descriptor CPE 401/601 Lecture 12 : I/O Multiplexing

38 Issues and Ideas Error Handling

39 System Calls and Errors
In general, systems calls return a negative number to indicate an error We often want to find out what error Servers generally add this information to a log Clients generally provide some information to the user CPE 401/601 Lecture 12 : Error Handling

40 extern int errno; Whenever an error occurs, system calls set the value of the global variable errno You can check errno for specific errors errno is valid only after a system call has returned an error System calls don't clear errno on success If you make another system call you may lose the previous value of errno printf makes a call to write! CPE 401/601 Lecture 12 : Error Handling

41 Error codes Error codes are defined in errno.h Support routines
EAGAIN EBADF EACCESS EBUSY EINTR EINVAL EIO ENODEV EPIPE … Support routines void perror(const char *string); stdio.h char *strerror(int errnum); string.h CPE 401/601 Lecture 12 : Error Handling

42 General Strategies Include code to check for errors after every system call Develop "wrapper functions" that do the checking for you Develop layers of functions, each hides some of the error-handling details CPE 401/601 Lecture 12 : Error Handling

43 Example wrapper int Socket( int f, int t, int p) { int n; if ( (n=socket(f,t,p)) < 0 ) ) { perror("Fatal Error"); exit(1); } return(n); CPE 401/601 Lecture 12 : Error Handling

44 What is fatal? How do you know what should be a fatal error?
Common sense If the program can continue – it should if a server can't create a socket, or can't bind to it's port there is no sense continuing… CPE 401/601 Lecture 12 : Error Handling

45 Wrappers are great! Wrappers like those used in the text can make code much more readable There are always situations in which you cannot use the wrappers Sometimes system calls are "interrupted" (EINTR) this is not always a fatal error ! CPE 401/601 Lecture 12 : Error Handling

46 Another approach Instead of simple wrapper functions, you might develop a layered system The idea is to "hide" the sockaddr and error handling details behind a few custom functions: int tcp_client(char *server, int port); int tcp_server(int port); CPE 401/601 Lecture 12 : Error Handling

47 Layers and Code Re-use Developing general functions that might be re-used in other programs is obviously "a good thing" Layering is beneficial even if the code is not intended to be re-used: hide error-handling from "high-level" code hide other details often makes debugging easier CPE 401/601 Lecture 12 : Error Handling

48 The Best Approach to handling errors
There is no best approach Do what works for you Make sure you check all system calls for errors! Not checking can lead to security problems! Not checking can lead to bad grades on assignments! CPE 401/601 Lecture 12 : Error Handling


Download ppt "Lecture 11 Overview."

Similar presentations


Ads by Google