260 likes | 422 Views
Sockets. Socket = abstraction of the port concept: Application programs request that the operating system create a socket when one is needed O.S. returns a small integer ( socket descriptor ) that the program uses to reference the socket
E N D
Sockets • Socket = abstraction of the port concept: • Application programs request that the operating system create a socket when one is needed • O.S. returns a small integer (socket descriptor) that the program uses to reference the socket • Application program can then use read and write system calls on the socket • Program closes the socket when finished using it
Creating a Socket • The socket system call: int sd; // socket descriptor int pf; // protocol family (one of PF_INET, // PF_PUP, PF_APPLETALK, // PF_UNIX, etc.) int type; // type of service (one of SOCK_RAW, // SOCK_DGRAM, SOCK_STREAM) int protocol; // specific protocol in pf sd = socket(pf, type, protocol) // create a new socket
Binding a Socket to an Internet Source Address (cont) • The bind system call: int sd; // socket descriptor struct sockaddr_in addr; // structure specifying source // address int len; // length (in bytes) of // addr struct bind(sd,addr,len) // bind socket to source IP // address
Connecting a Socket to a Destination Address • The connect system call: int sd; // socket descriptor struct sockaddr addr; // structure specifying dest addr int len; // length (in bytes) of // addr struct connect(sd,addr,len) // connect socket to // dest address • Can also use a sockaddr_in struct for dest address
Sending Data Through a Socket • The write system call: int sd; // socket descriptor void *buffer; // address of the data to be sent int len; // number of bytes to send write(sd,buffer,len) // send data through socket
Receiving Data Through a Socket • The read system call: int sd; // socket descriptor void *buffer; // address in memory at which // to store the data int len; // number of bytes to receive read(sd,buffer,len) // receive data through socket
Closing a Socket • The close system call: int sd; // socket descriptor close(sd) // close socket
Datagram Socket Example: Receiver #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> main() { int sock, len; struct sockaddr_in name; char buf [1024]; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) exit(-1); name.sin_family = AF_INET; name.sin_addr.s_addr = INADDR_ANY; name.sin_port = 0; if (bind(sock, (struct sockaddr *) &name, sizeof(name))) exit(-1); len = sizeof(name); if (getsockname(sock, (struct sockaddr *) &name, &len)) exit(-1); printf("Receiver listening on port %d\n",ntohs(name.sin_port)); if (read(sock, buf, 1024) < 0) exit(-1); printf("%s\n",buf); close(sock); }
Datagram Socket Example: Sender #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <string.h> main(int argc, char **argv) { int sock; struct sockaddr_in name; struct hostent *hp, *gethostbyname(); if (argc != 3) exit(-1); sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) exit(-1); hp = gethostbyname("prime.cs.ohiou.edu"); if (hp == 0) exit(-1); bcopy(hp->h_addr, &name.sin_addr, hp->h_length); name.sin_family = AF_INET; name.sin_port = htons(atoi(argv[1])); if (connect(sock, (struct sockaddr *) &name, sizeof(name))) exit(-1); if (write(sock, argv[2], (strlen(argv[2])+1)) < 0) exit(-1); close(sock); }
Obtaining Local Socket Addresses • The getsockname system call: int sd; // socket descriptor struct sockaddr *addr; // address structure to be filled int *len; // pointer to integer that will // contain the length of the // address getsockname(sd, addr, len); // obtain local socket address
Obtaining and SettingSocket Options • The getsockopt system call: int sd; // socket descriptor int level; // option for socket or protocol? int optionid; // which specific option? void *optionval; // where to place the requested // value int *len; // length of the optionval getsockopt(sd, level, optionid, optionval, len); // obtain // socket opt
Obtaining and SettingSocket Options (cont) • Values for level (from <netinet/in.h>): • SOL_SOCKET option for the socket • IPPROTO_IP option for IP • IPPROTO_ICMP option for ICMP • IPPROTO_TCP option for TCP • IPPROTO_UDP option for UDP
Obtaining and SettingSocket Options (cont) • Values for optionid (from <sys/socket.h>): • SO_TYPE socket type • SO_SNDBUF send buffer size • SO_RCVBUF receive buffer size • SO_DEBUG debugging info available? • SO_ACCEPTCONN socket listening enabled? • SO_BROADCAST broadcast supported? • SO_REUSEADDR address reuse allowed? • SO_KEEPALIVE keep alive after close?
Obtaining and SettingSocket Options (cont) • The setsockopt system call: int sd; // socket descriptor int level; // option for socket or protocol? int optionid; // which specific option? void *optionval; // option value int *len; // length of the option value setsockopt(sd, level, optionid, optionval, len); // set option // value
Socket Options for Servers • The listen system call: int sd; // socket descriptor int length; // length of request queue listen(sd, length) // set socket request queue // length • Can only be used for SOCK_STREAM sockets
Servers: Accepting Connections • The accept system call: int sd; // socket descriptor struct sockaddr *name; // address of client int *len; // length of address struct newsock = accept(sd, addr, len) // accept connection • A new socket is created that connects to the client • Server handles request, sends reply, closes newsock
Servers That ProvideMultiple Services • The select system call: int ndesc; // check descriptors 0...ndesc-1 void *indesc; // descriptors to check for input void *outdesc; // descriptors to check for output void *excdesc; // descriptors to check for exceptions int *timeout; // how long to wait for a connection nready = select(ndesc, indesc, outdesc, excdesc, timeout) // determine which descriptors are // ready for I/O
Servers That ProvideMultiple Services (cont) • The select system call: nready = select(ndesc, indesc, outdesc, excdesc, timeout) • Returns the number of descriptors from the specified set that are ready for I/O • A process can use select to communicate over more than one socket at a time • Typically each socket provides a distinct service
Miscellaneous (Useful)System Calls • The gethostname system call: char *name; // buffer to store name int length; // size of buffer in bytes gethostname(name, length) // get name of host • Defined in <netdb.h> include file • Process can learn host it’s running on
Miscellaneous (Useful)System Calls (cont) • The network byte order conversion routines: • Network-to-host (short), ntohs, convert a short int from network byte order to host byte order • Network-to-host (long), ntohl, convert a long int from network byte order to host byte order • Host-to-network (short), htons, convert a short int from network byte order to host byte order • Host-to-network (long), htonl, convert a long int from network byte order to host byte order
Miscellaneous (Useful)System Calls (cont) • Testing htons: #include <stdio.h> #include <string.h> #include <netdb.h> main(int argc, char **argv) { if (argc != 2) exit(-1); printf("%d\n",atoi(argv[1])); printf("%d\n",htons(atoi(argv[1]))); }
Miscellaneous (Useful)System Calls (cont) • The gethostbyname system call: struct hostent *h; // hostent structure char *name; // host name h = gethostbyname(name); // fill in hostent with // info about name
Miscellaneous (Useful)System Calls (cont) • The hostent structure (defined in <netdb.h>): struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses from name server */
OHCE Server Example • Check that program is running on the proper host • Create a socket on which the server will receive requests • Bind the socket to the well-known port for the ohce service • Loop forever • Receive request and process it • Send reply to port and machine specified in the client’s request
OHCE Client Example • Create a socket on which to receive the server’s reply • Bind it to some port on the local machine • Create a socket on which to send a request to the server • Bind it to the port the server’s listening on • Create a request message and send it to the server • Wait for a reply and print out the result
Summary • The client-server model is widely-used for application interaction over a TCP/IP internet • Server: a program that offersa service that can be reached over a network • Examples: web server, file server • Client: a program that requests a service from a server • Examples: ping, browser • Application programs typically interact with the networking software by using sockets and system calls: • Socket – create a socket • Bind – bind a socket to a port • Read/write – get/put data in a socket • Etc.