290 likes | 507 Views
Socket structure in C. struct sockaddr_in { //Address family, always AF_INET short int sin_family; // Port number unsigned short int sin_port; // struct for IP address struct in_addr sin_addr; // A part that is always zero unsigned char sin_zero[8]; }; .
E N D
Socket structure in C struct sockaddr_in { //Address family, always AF_INET short int sin_family; // Port number unsigned short int sin_port; // struct for IP addressstruct in_addr sin_addr; // A part that is always zerounsigned char sin_zero[8]; }; struct in_addr { // IP address 32-bitunsigned long s_addr; }; 2: Application Layer
Host and Network Byte Order • Network byte order is “most significant byte first”1.2.3.4 stored as • Host byte order could be either “most significant byte first” or “least significant byte first” 1.2.3.4 stored as • There are functions to convert a number between host and network byte order:long htonl(long)short htons(short)long ntohl(long)short ntohs(short) 1 2 3 4 4 3 2 1 2: Application Layer
Socket structure in C struct sockaddr_in { //Address family, always AF_INET short int sin_family; // Port number unsigned short int sin_port; // struct for IP addressstruct in_addr sin_addr; // A part that is always zerounsigned char sin_zero[8]; }; network order network order Sockets are referenced via a socket descriptor which is of type int There is also a struct called sockaddr and some functions need that datatype as an argument 2: Application Layer
IP address (32-bit string) • To obtain a 32-bit address in network orderfrom a string long inet_addr(“1.2.3.4”) • To obtain a dotted-notation string from the address in 32-bit char* inet_ntoa(struct in_addr) 2: Application Layer
Using DNS struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; }; First element is called haddr //Getting yahoo’s IP address struct hostent h; struct in_addr in; //Call DNS h=gethostbyname(“www.yahoo.com”); //Create address struct so we can call inet_ntoa in.s_addr = h->haddr; printf(“Address is %s\n”, inet_ntoa(in)); 2: Application Layer
Example client-server app: 1) client gets a line from theserver and prints it out C Socket programming using TCP 2. connect 1. waiting on a port server client 3. line 2: Application Layer
C client using TCP #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> // the port client will be connecting to#define PORT 3490 // max number of bytes we can get at once #define MAXDATASIZE 100 2: Application Layer
C client using TCP int main(int argc, char *argv[]) { int sockfd, numbytes; char buf[MAXDATASIZE]; struct hostent *he; // server's address struct sockaddr_in server_addr; //error checking if (argc != 2) { fprintf(stderr,"usage: client hostname\n"); exit(1); } 2: Application Layer
C client using TCP // get the host info via DNS if ((he=gethostbyname(argv[1])) == NULL) { perror("gethostbyname"); exit(1); } // create the socket, this will not automatically connect it if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } 2: Application Layer
C client using TCP // fill in server data server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); server_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(&(server_addr.sin_zero), '\0', 8); // connect to server (handshaking) if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } 2: Application Layer
C client using TCP // receive data from server if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror("recv"); exit(1); } // put the end-of-string character and print it out buf[numbytes] = '\0'; printf("Received: %s",buf); // close socket and exit close(sockfd); return 0; } 2: Application Layer
C server using TCP #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/wait.h> #include <signal.h> // the port users will be connecting to #define MYPORT 3490 // how many pending connections queue will hold #define BACKLOG 10 2: Application Layer
C server using TCP int main(void) { int welcomesock, connectionsock; // my address information struct sockaddr_in my_addr; // client address information struct sockaddr_in client_addr; socklen_t sin_size; int yes=1; // create socket for waiting if ((welcomesock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } 2: Application Layer
C server using TCP // sockets usually take some time to be released by OS// doing this ensures that you can re-run your server right // after it exits, on the same port if(setsockopt(welcomesock,SOL_SOCKET,SO_REUSEADDR, &yes,sizeof(int)) == -1) { perror("setsockopt"); exit(1); } // fill in my address datamy_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); // automatically fill IP address of this machinemy_addr.sin_addr.s_addr = INADDR_ANY; memset(&(my_addr.sin_zero), '\0', 8); // zero the rest 2: Application Layer
C server using TCP // associate welcome socket with port if (bind(welcomesock, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } // start waiting for clients if (listen(welcomesock, BACKLOG) == -1) { perror("listen"); exit(1); } 2: Application Layer
C server using TCP // loop foreverwhile(1) { sin_size = sizeof(struct sockaddr_in); // accept client’s connection if ((clientsock = accept(welcomesock, (struct sockaddr *)&client_addr, &sin_size)) == -1) { perror("accept"); continue; } // print a message about new connection printf("server: got connection from %s\n", inet_ntoa(client_addr.sin_addr)); 2: Application Layer
C server using TCP // send server’s message if (send(clientsock, "Hello, world!\n", 14, 0) == -1) { perror("send"); close(clientsock); exit(0); } // close this connection with the client close(clientsock); } //end of loop forever //close welcome socket and exit close(welcomesock); return 0; } 2: Application Layer
Example client-server app: 1) client sends a line to the server C Socket programming using UDP 2. line 1. waiting on a port server client 2: Application Layer
C client using UDP #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> // the port client will be connecting to#define PORT 3490 // max number of bytes we can get at once #define MAXDATASIZE 100 2: Application Layer
C client using UDP int main(int argc, char *argv[]) { int sockfd, numbytes; char buf[MAXDATASIZE]; struct hostent *he; // server's address struct sockaddr_in server_addr; //error checking if (argc != 2) { fprintf(stderr,"usage: client hostname\n"); exit(1); } 2: Application Layer
C client using UDP // get the host info via DNS if ((he=gethostbyname(argv[1])) == NULL) { perror("gethostbyname"); exit(1); } // create the socket if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1); } 2: Application Layer
C client using UDP // fill in server data server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); server_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(&(server_addr.sin_zero), '\0', 8); // send message to server if ((numbytes=sendto(sockfd, “Hi\n”, 3, 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(1); } // close socket and exit close(sockfd); return 0; } 2: Application Layer
C server using UDP #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/wait.h> #include <signal.h> // the port users will be connecting to #define MYPORT 3490 2: Application Layer
C server using UDP int main(void) { int welcomesock; // my address information struct sockaddr_in my_addr; // client address information struct sockaddr_in client_addr; socklen_t sin_size; int yes=1; // create socket for waiting if ((welcomesock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1); } 2: Application Layer
C server using UDP // sockets usually take some time to be released by OS// doing this ensures that you can re-run your server right // after it exits, on the same port if(setsockopt(welcomesock,SOL_SOCKET,SO_REUSEADDR, &yes,sizeof(int)) == -1) { perror("setsockopt"); exit(1); } // fill in my address datamy_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); // automatically fill IP address of this machinemy_addr.sin_addr.s_addr = INADDR_ANY; memset(&(my_addr.sin_zero), '\0', 8); // zero the rest 2: Application Layer
C server using UDP // associate welcome socket with port if (bind(welcomesock, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } 2: Application Layer
C server using UDP // loop foreverwhile(1) { addr_len = sizeof(struct sockaddr); // get a packet, no listen or accept if ((numbytes = recvfrom(welcomesock, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&client_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1); } // print a message about client printf("server: got message from %s\n", inet_ntoa(client_addr.sin_addr)); 2: Application Layer
C server using UDP printf("packet is %d bytes long\n",numbytes); buf[numbytes] = '\0'; printf("packet contains \"%s\"\n",buf); } } //end of loop forever // close welcome socket and exit close(welcomesock); return 0; } 2: Application Layer