Socket Programming15-441 Computer Networks, Spring 2008Xi LiuLecture Today• Motivation for sockets• What’s in a socket?• Working with socket• Concurrent network applications• Project 1Why Socket?• How can I program a network application?– Share data– Send messages– Finish course projects...• IPC - Interprocess CommunicationNetwork LayeringApplicationPresentationSessionTransportNetworkData linkPhysical1234567NetworkData linkPhysicalApplicationPresentationSessionTransportNetworkData linkPhysicalNetwork Layering• Why layering?ApplicationPresentationSessionTransportNetworkData linkPhysical1234567NetworkData linkPhysicalApplicationPresentationSessionTransportNetworkData linkPhysicalLayering Makes it Easier• Application programmer– Doesn’t need to send IP packets– Doesn’t need to send Ethernet frames– Doesn’t need to know how TCP implements reliability• Only need a way to pass the data down– Socket is the API to access transport layer functionsWhat Lower Layer Need to Know?• We pass the data down. What else does the lower layer need to know?What Lower Layer Need to Know?• We pass the data down. What else does the lower layer need to know?• How to identify the destination process?– Where to send the data? (Addressing)– What process gets the data when it is there? (Multiplexing)Identify the DestinationConnection socket pair(128.2.194.242:3479, 208.216.181.15:80)HTTP Server(port 80)ClientClient socket address128.2.194.242:3479Server socket address208.216.181.15:80Client host address128.2.194.242Server host address208.216.181.15FTP Server(port 21)• Addressing– IP address– hostname (resolve to IP address via DNS)• Multiplexing– portSockets• How to use sockets– Setup socket• Where is the remote machine (IP address, hostname)• What service gets the data (port)– Send and Receive• Designed just like any other I/O in unix• send -- write• recv -- read– Close the socketClient / ServerSessionClient Serversocket socketbindlistenreadwritereadwriteConnectionrequestreadclosecloseEOFopen_listenfdacceptconnectopen_clientfdOverviewStep 1 – Setup Socket• Both client and server need to setup the socket– int socket(int domain, int type, int protocol);• domain– AF_INET -- IPv4 (AF_INET6 for IPv6)• type– SOCK_STREAM -- TCP– SOCK_DGRAM -- UDP• protocol– 0• For example,– int sockfd = socket(AF_INET, SOCK_STREAM, 0);Step 2 (Server) - Binding • Only server need to bind– int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);• sockfd– file descriptor socket() returned• my_addr– struct sockaddr_in for IPv4– cast (struct sockaddr_in*) to (struct sockaddr*)struct sockaddr_in {short sin_family; // e.g. AF_INETunsigned short sin_port; // e.g. htons(3490)struct in_addr sin_addr; // see struct in_addr, belowchar sin_zero[8]; // zero this if you want to};struct in_addr {unsigned long s_addr; // load with inet_aton()};What is that Cast?• bind() takes in protocol-independent (structsockaddr*)– C’s polymorphism– There are structs for IPv6, etc.struct sockaddr {unsigned short sa_family; // address familychar sa_data[14]; // protocol address};Step 2 (Server) - Binding contd.• addrlen– size of the sockaddr_instruct sockaddr_in saddr;int sockfd;unsigned short port = 80;if((sockfd=socket(AF_INET, SOCK_STREAM, 0) < 0) { // from back a couple slidesprintf(“Error creating socket\n”);...}memset(&saddr, '\0', sizeof(saddr)); // zero structure outsaddr.sin_family = AF_INET; // match the socket() callsaddr.sin_addr.s_addr = htonl(INADDR_ANY); // bind to any local addresssaddr.sin_port = htons(port); // specify port to listen onif((bind(sockfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { // bind!printf(“Error binding\n”);...}What is htonl(), htons()?• Byte ordering– Network order is big-endian– Host order can be big- or little-endian• x86 is little-endian• SPARC is big-endian• Conversion– htons(), htonl(): host to network short/long– ntohs(), ntohl(): network order to host short/long• What need to be converted?– Addresses– Port– etc.Step 3 (Server) - Listen• Now we can listen– int listen(int sockfd, int backlog);• sockfd– again, file descriptor socket() returned• backlog– number of pending connections to queue• For example,– listen(sockfd, 5);Step 4 (Server) - Accept• Server must explicitly accept incoming connections– int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)• sockfd– again... file descriptor socket() returned• addr– pointer to store client address, (struct sockaddr_in *) cast to (struct sockaddr *)• addrlen– pointer to store the returned size of addr, should be sizeof(*addr)• For example– int isock=accept(sockfd, (struct sockaddr_in *) &caddr, &clen);Put Server Togetherstruct sockaddr_in saddr, caddr;int sockfd, clen, isock;unsigned short port = 80;if((sockfd=socket(AF_INET, SOCK_STREAM, 0) < 0) { // from back a couple slidesprintf(“Error creating socket\n”);...}memset(&saddr, '\0', sizeof(saddr)); // zero structure outsaddr.sin_family = AF_INET; // match the socket() callsaddr.sin_addr.s_addr = htonl(INADDR_ANY); // bind to any local addresssaddr.sin_port = htons(port); // specify port to listen onif((bind(sockfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { // bind!printf(“Error binding\n”);...}if(listen(sockfd, 5) < 0) { // listen for incoming connectionsprintf(“Error listening\n”);...}clen=sizeof(caddr)if((isock=accept(sockfd, (struct sockaddr *) &caddr, &clen)) < 0) { // accept oneprintf(“Error accepting\n”);...}What about client?• Client need not bind, listen, and accept• All client need to do is to connect– int connect(int sockfd, const struct sockaddr*saddr, socklen_t addrlen);• For example,– connect(sockfd, (struct sockaddr *) &saddr, sizeof(saddr));Domain Name System (DNS)• What if I want to send data to “www.slashdot.org”?– DNS: Conceptually, DNS is a database collection of host entries• hostname -> IP address– struct hostent *gethostbyname(const char *name);• IP address -> hostname– struct hostent *gethostbyaddr(const char *addr, int len, inttype);struct hostent {char *h_name; // official hostnamechar **h_aliases; // vector of alternative hostnamesint h_addrtype; // address type, e.g. AF_INETint h_length; // length of address in bytes, e.g. 4 for IPv4char **h_addr_list; // vector of addresseschar
View Full Document