Server Sockets: A server socket listens on a given port Many different clients may be connecting to...

21
Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor for each client connection Web Server Client 1 Client 2 Client 3 Client n Server Socket/Port

Transcript of Server Sockets: A server socket listens on a given port Many different clients may be connecting to...

Page 1: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Server Sockets:

• A server socket listens on a given port• Many different clients may be connecting to that port• Ideally, you would like a separate file descriptor for each client connection

Web Server

Client 1 Client 2 Client 3 Client n

Server Socket/Port

Page 2: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Server Sockets:

Client 1

Web ServerServer Socket/PortNew socket

2: Server creates new file descriptor for client which is used for bi-directional communication. All futurecommunication withclient is done with thisnew file descriptor.

Client 2

1: Client requests connection

3: Other clients requesting connections can now be serviced.

Page 3: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Server Sockets

• How to use the socket API to listen for an accept connections

• Start by describing a non-concurrent implementation of a server (only one thread of execution)The code I provided for project 5 is a non-concurrent implementation. You will modify it to make it concurrent.

• Procedure– Create network endpoint with socket()– Bind socket to a port - bind()– Start listening for connections - listen()– Loop and accept connections - accept()– Read and write data to client - send(), recv(), read(), write()

Page 4: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

int socket(int domain, int type, int protocol);

Creating the Socket

For IP (Internet Protocol), use AF_INET.For communication within a single machine, use AF_UNIX

For TCP, use SOCK_STREAMFor UDP, use SOCK_DGRAM

This argument is for making a selection if the type (the previous argument) offers a choice. 0 is the default and should be used in most cases.

Returns file descriptor or -1

if ((sockfd = socket(AF_INET,SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1);}

Socket() creates an endpoint for network communication

Page 5: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Internet Protocol

The Internet protocol family is comprised of the Internet Protocol ("IP"), the Address Resolution Protocol ("ARP"), the Internet Control Message Protocol ("ICMP"), the Transmission Control Protocol ("TCP"), and the User Datagram Protocol ("UDP").

Page 6: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Bind the Socket to a Port

• Ports allow multiple network processes on a machine with a single address.

• A server has to choose a port where clients can contact it.

• It is important that standard services be at the same port on all computers so that clients will know their addresses. The FTP port is 21. The usual port for a web server is 80. Port numbers above 2000 are generally available.

• bind() associates the chosen port with a socket already created with the socket() command.

Page 7: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

bind() connects a server socket to a port

int bind(int sockfd, struct sockaddr *address, size_t add_len);

Binding the socket

0 on success or -1 on error

if (bind(sockfd, (struct sockaddr *) &server, sizeof(server)) == -1) { perror("bind call failed"); exit(1);}

Network address structure identifying port to listen on. See next slide.

Size of address structure

The int returned from socket call.

Page 8: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

2nd Argument of bind

• even though bind() wants a struct sockaddr*, you can still use a struct sockaddr_in and cast it to be a sockaddr *

Page 9: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Setting up an address

The sockaddr_in structure is used to set up an internet address.

This structure is defined in <netinet/in.h>. struct sockaddr_in server;

server.sin_family = AF_INET;

server.sin_port = htons(7000);

server.sin_addr.s_addr = INADDR_ANY;

server.sin_zero[8] /* not used */

Page 10: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Argument 1 of sockaddr_in sin_family

• We want communication across different machines so we will not use AF_UNIX.

• We will use AF_INET.

• This should be the same as you used in the first argument of the socket call.

Page 11: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Argument 2 of sockaddr_in sin_port

• The second field of serv_addr_in is unsigned short sin_port , which contain the port number. However, instead of simply copying the port number to this field, it is necessary to convert this to network byte order using the function htons() which converts a port number in host byte order to a port number in network byte order.

• Different machines store numbers differently internally. Some are big endian, some are little endian. htons lets computers with different schemes communicate. See next slide.

Page 12: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Big endian and Little endian computers

• Virtually all computer architectures are byte addressable. If an int is four bytes, there are two different ways to store this. Suppose the address of the int is A. In a so-called big endian computer, the highest order byte is stored at A, and the lowest order byte is stored at address A+3. In a so-called little endian computer, address A stores the least significant byte and the most significant byte is at address A+3.

Page 13: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Argument 3 of sockaddr_in sin_addr

• The sin_addr field of the sockaddr_in structure specifies a local or remote IP address. Each network interface has its own unique IP address. The special value INADDR_ANY may be used in this field to effect "wildcard" matching. Given in a bind() call, this value leaves the local IP address of the socket unspecified, so that the socket will receive connections or messages directed at any of the valid IP addresses of the system.

Page 14: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Argument 4 of sockaddr_in sin_zero[8]

• sin_zero (which is included to pad the structure to the length of a struct sockaddr) should be set to all zeros with the function memset().

Page 15: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Listening for Connections

• The server will ignore any connection attempts until you tell the socket() to start listening

• This is done with listen()

Page 16: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

listen() causes the socket to start listening for connections

int listen(int sockfd, int queue_size);

Listen

0 on success or -1 on error

if (listen(sockfd, 5) == -1) { perror("listen call failed"); exit(1);}

Maximum numbers of connections to queue up

Page 17: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

listen()

• The first argument is the socket file descriptor, and the second is the size of the backlog queue, i.e., the number of connections that can be waiting while the process is handling a particular connection. This should be set to 5, the maximum size permitted by most systems. If the first argument is a valid socket, this call cannot fail.

Page 18: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Loop and Accept

• Servers generally run continually, waiting for clients to contact them.

• Thus a server has an "infinite loop" that continually processes connections from clients.

• The accept() function takes the next connection off the listen queue or blocks the process until a connection arrives.

Page 19: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Project 5

• The code I supplied with project 5 does not have this infinite loop. You will modify the code I gave you to put accept() in this loop. accept() blocks until a client connects. Every time a client connects, you should fork off a child and let the child handle the communication with the client. Meanwhile the parent will go back to accept more client connections.

Page 20: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

Accept Returns a New File Descriptor

• Your child will communicate with the client using the new file descriptor NOT the file descriptor returned by socket.

• Your parent will close its copy of the new file descriptor because it will not be involved with further communication with the client after the connection is made. Don’t forget to implement signal handling for SIGCHLD. You MUST wait for these children when they finish.

Page 21: Server Sockets: A server socket listens on a given port Many different clients may be connecting to that port Ideally, you would like a separate file descriptor.

accept() returns the next client connection

int accept(int sockfd, struct sockaddr *address, size_t &add_len);

Accept

Returns file descriptor or -1

while (1) { client_sockfd = accept(sockfd, NULL, NULL); if (client_sockfd == -1) { perror("accept call failed"); /* Here you may want to continue or exit - depends */ }}

Network address structure identifying client. This can be NULL pointer

Pointer to variable containing size of address structure, can be NULL