Monday, April 5, 2010

Lecture 16 TCP and UDP Sockets

This lecture covers the creation of sockets for TCP and UDP connections. To create a TCP socket one must call a function socket(PF_INET, SOCK_STREAM, 0) which returns a positive integer reference to the newly created socket or a negative return indicates the failure in creating a new socket. A newly created socket can be bound to specific port and address by using the bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen) or a user can let the operating system take care of it.

A server that is needs to accept incoming TCP connections needs to establish a passive mode TCP socket. This is done by using the function listen(int sockfd, int backlog) which takes a socket reference and an integer specify a total number of connections to queue for the server. The intricacies of establishing a TCP connection are handled by the operating system, all the server has to do is call accept(int sockfd, struct sockaddr* cliaddr, socklen_t *addrlen) with a predefined socket, and a location to hold the struct used to define the client's address. The accept function will return a socket reference in the form of a positive integer or a negative value indicating that an error has occurred. To operate on an active TCP socket, read and write functions may be used to send and receive data from and to the socket. To terminate a TCP connection, calling a close function will handle all the TCP details involved in the termination of a connection. For a client, to connect to a server, a connect function may be used to establish a TCP connection. The connect function must be supplied with an initialized socket reference along with information in regards to the address of the server to connect to. Upon a successful connect, the read and write functions may be used to send and receive data.

To create a UDP socket, socket(...) is called using the SOCK_DGRAM constant for the type parameter. Binding of an address is also available to UDP sockets and the process is the same as the one for TCP socket connections. Since UDP is connectionless, once a socket has been established, data can immediately be sent from it using sendto(...) which takes in, besides the usual socket descriptor and data, the destination address in the form of a structure. This function returns with a value indicating the number of bytes that the operating system accepted to be sent. Since UDP is unreliable, there is no indicator of how much of the sent data actually made it to the destination. To receive data a recvfrom(...) function may be called with the address of the sender specified along with buffer space and a socket descriptor. Since UDP is unreliable and recvfrom(...) is a blocking call, several countermeasures must be taken to avoid waiting for lost packets. One of which is to using a SIGALRM which basically throws an error for the recvfrom function when a specified amount of time is used.

An interesting feature available in the API is a "connected mode" for UDP which basically allows for the use of sendto() without specifying destination address as well as write(), send(), read(), and recv() commands for that socket descriptor. This however is only a convenience, it does not establish an actual connection with teh peer.

No comments:

Post a Comment