Overview Introduction to UNIX commands Text editors CC

  • Slides: 50
Download presentation
Overview Introduction to UNIX commands Text editors C/C++ compiling Sockets

Overview Introduction to UNIX commands Text editors C/C++ compiling Sockets

UNIX Commands change directory: cd dirname change to home dir: cd copy a file:

UNIX Commands change directory: cd dirname change to home dir: cd copy a file: cp old new move (rename) a file: mv old new remove a file: rm fname print working directory: pwd a new directory: mkdir new get the manual for command: man command type contents of a file: cat filename show by screens: less filename somecommand option argument|less count lines, words, chars: wc filename find a file in current dir: find. –name foo. bar -print search for something in files: grep “some thing” filename grep something /some/path/*. c grep –r something /some/folder

Text Editors in UNIX VI (Visually Improved). Example: vi filename. c Enter : q

Text Editors in UNIX VI (Visually Improved). Example: vi filename. c Enter : q to quit. Pico is similar to Pine mail user agent. Good for first time UNIX users. Emacs GNU Emacs Manual: http: //www. delorie. com/gnu/docs/emacs_toc. html XEmacs A version for X-Windows. Some exotic editors for linux out there now (anjuta, kwrite …)

Compilng C/C++ Compiling with gcc –o tcp. Client. c other. File. c –lnsl Use

Compilng C/C++ Compiling with gcc –o tcp. Client. c other. File. c –lnsl Use g++ in the same way for C++ files You should not ignore warnings. On unix machines, need –lnsl -lsocket; they link in the name services library and the sockets library. On Linux, you don’t need –lsocket – socket support is part of std C library

Sockets Programming Socket to me!

Sockets Programming Socket to me!

Outline What is a socket? Preliminaries Ports Data structures and conversion DNS resolution TCP

Outline What is a socket? Preliminaries Ports Data structures and conversion DNS resolution TCP server with example UDP server with example Select() for concurrent servers

Network Application Programming Interface (API) The services provided (often by the operating system) that

Network Application Programming Interface (API) The services provided (often by the operating system) that provide the interface between application and protocol software. Application Sockets Do this Network API TCP UDP Etc…

Socket Basics An end-point for a IP network connection End point determined by two

Socket Basics An end-point for a IP network connection End point determined by two things: what the application layer “plugs into” programmer cares about Application Programming Interface (API) Host address: IP address is Network Layer Port number: is Transport Layer Two end-points determine a connection: socket pair ex: 128. 226. 123. 101, p 21 + 198. 69. 10. 2, p 1500 ex: 128. 226. 123. 101, p 21 + 198. 69. 10. 2, p 1499

Aside -- Ports Numbers (vary by OS): 0 -1023 “reserved”, must be root to

Aside -- Ports Numbers (vary by OS): 0 -1023 “reserved”, must be root to use 1024 - 5000 “ephemeral” however, many systems allow > 3977 ports (50, 000+ common) Well-known, reserved services (see /etc/services in Unix): ftp 21/tcp ssh 22/tcp telnet 23/tcp finger 79/tcp snmp 161/udp

Transport Layer UDP: User Datagram Protocol no acknowledgements no retransmissions out of order, duplicates

Transport Layer UDP: User Datagram Protocol no acknowledgements no retransmissions out of order, duplicates possible connectionless TCP: Transmission Control Protocol reliable (in order, all arrive, no duplicates) flow control connection

Socket Descriptor Data Structure Descriptor Table 0 1 2 3 4 Family: PF_INET Service:

Socket Descriptor Data Structure Descriptor Table 0 1 2 3 4 Family: PF_INET Service: SOCK_STREAM Local IP: 111. 22. 3. 4 Remote IP: 123. 45. 6. 78 Local Port: 2249 Remote Port: 3726

Preliminaries

Preliminaries

Socket Address Structure struct in_addr { in_addr_t s_addr; }; struct sockaddr_in { unit 8_t

Socket Address Structure struct in_addr { in_addr_t s_addr; }; struct sockaddr_in { unit 8_t sin_len; sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; char sin_zero[8]; } /* 32 -bit IPv 4 addresses */ /* length of structure */ /* AF_INET */ /* TCP/UDP Port num */ /* IPv 4 address (above) */ /* unused */ Are also “generic” and “IPv 6” socket structures

Convert the natives! Byte order ‘h’ : host byte order ‘s’ : short (16

Convert the natives! Byte order ‘h’ : host byte order ‘s’ : short (16 bit) ‘n’ : network byte order ‘l’ : long (32 bit) uint 16_t htons(uint 16_t); uint 16_t ntohs(uint_16_t); uint 32_t htonl(uint 32_t); uint 32_t ntohl(uint 32_t); In_addr values should be stored in network byte order (common mistake)

Aside – Using DNS server Sockets use IP addresses to name hosts Use DNS

Aside – Using DNS server Sockets use IP addresses to name hosts Use DNS to resolve host names to IP addresses DNS is the “phone book” that maps machine names to IP addresses Done before Initiating a connection

Using DNS To find out the IP address of a machine #include <unistd. h>

Using DNS To find out the IP address of a machine #include <unistd. h> int gethostname(char *name, int namelen); name : is character array way to store the name Of the machine with null terminated character. namelen : size of the chracter array This function puts the name of the host in name. It returns 0 if ok, -1 if error.

gethostbyname (cont) #include <netdb. h> struct hostent *gethostbyname(const char *name); This returns hostent structure

gethostbyname (cont) #include <netdb. h> struct hostent *gethostbyname(const char *name); This returns hostent structure with all necessary information related to host with name. struct hostent { char *h_name; /* canonical 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 */ }; #define h_addr_list[0]

hostent Address stored in h_addr is in struct in_addr form. To obtain “. ”

hostent Address stored in h_addr is in struct in_addr form. To obtain “. ” separated id address we could use #include <sys/types. h> #include <sys/socket. h> #include <netinet/in. h> #include <arpa/inet. h> char *inet_ntoa(const struct in_addr in); The routine inet_ntoa() returns a pointer to a string in the base 256 notation d. d.

IP Addresses and how to deal with them ASCII to 32 -bit IP: ina.

IP Addresses and how to deal with them ASCII to 32 -bit IP: ina. sin_addr. s_addr = inet_addr("10. 12. 110. 57"); Also can use inet_aton (ascii to network) 32 -bit IP to ASCII a 1 = inet_ntoa(ina 2. sin_addr); // this is 10. 12. 110. 57 printf("address 1: %sn", a 1);

socket() bind() TCP Client-Server “well-known” port listen() Client accept() (Block until connection) socket() “Handshake”

socket() bind() TCP Client-Server “well-known” port listen() Client accept() (Block until connection) socket() “Handshake” Data (request) recv() send() recv() close() connect() send() Data (reply) recv() End-of-File close()

creating a socket() int socket(int family, int type, int protocol); Create a socket/file descriptor,

creating a socket() int socket(int family, int type, int protocol); Create a socket/file descriptor, giving access to transport layer service. family is one of AF_INET (IPv 4), AF_INET 6 (IPv 6), AF_LOCAL (local Unix), AF_ROUTE (access to routing tables), AF_KEY (new, for encryption) type is one of SOCK_STREAM (TCP), SOCK_DGRAM (UDP) SOCK_RAW (for special IP packets, PING, etc. Must be root) setuid bit (-rws--x--x root 1997 /sbin/ping*) protocol is 0 (used for some raw socket options) upon success returns socket descriptor Integer, like file descriptor Return -1 if failure

bind()-- What is my port? ? int bind(int sockfd, const struct sockaddr *myaddr, socklen_t

bind()-- What is my port? ? int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen); Assign a local protocol address (“name”) to a socket. sockfd is socket descriptor from socket() myaddr is a pointer to address struct with: port number and IP address if port is 0, then host will pick ephemeral port IP address = INADDR_ANY (unless multiple nics) addrlen is length of structure returns 0 if ok, -1 on error EADDRINUSE (“Address already in use”)

bind() example int sd; struct sockaddr_in ma; sd = socket(AF_INET, SOCK_STREAM, 0); ma. sin_family

bind() example int sd; struct sockaddr_in ma; sd = socket(AF_INET, SOCK_STREAM, 0); ma. sin_family = AF_INET; ma. sin_port=htons(5100); ma. sin_addr. s_addr=htonl(INADDR_ANY); if(bind(sd, (struct sockaddr *) &ma, sizeof(ma))!= -1) { …}

listen() – will someone please talk to me? int listen(int sockfd, int backlog); Change

listen() – will someone please talk to me? int listen(int sockfd, int backlog); Change socket state for TCP server. sockfd is socket descriptor from socket() backlog is maximum number of incomplete connections historically 5 rarely above 15 on a even moderate Web server!

accept()– thank you for calling my port int accept(int sockfd, struct sockaddr cliaddr, socklen_t

accept()– thank you for calling my port int accept(int sockfd, struct sockaddr cliaddr, socklen_t *addrlen); Return next completed connection. sockfd is socket descriptor from socket() cliaddr and addrlen return protocol address from client returns brand new descriptor, created by OS note, if create new process or thread, can create concurrent server

listen/connect() example struct sockaddr_in ca; //After bind. . listen(sd, 5); calen = sizeof(ca); cd

listen/connect() example struct sockaddr_in ca; //After bind. . listen(sd, 5); calen = sizeof(ca); cd = accept(sd, (struct sockaddr *) ca, &calen); //read and write using cd

connect() int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen); Connect to server. sockfd

connect() int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen); Connect to server. sockfd is socket descriptor from socket() servaddr is a pointer to a structure with: addrlen is length of structure client doesn’t need bind() port number and IP address must be specified (unlike bind()) – how? OS will pick ephemeral port returns socket descriptor if ok, -1 on error

close()/shutdown – go away! int close(int sockfd); Close socket for use. sockfd is socket

close()/shutdown – go away! int close(int sockfd); Close socket for use. sockfd is socket descriptor from socket() closes socket for reading/writing returns (doesn’t block) attempts to send any unsent data socket option SO_LINGER . block until data sent or discard any remaining data returns -1 if error

connect() example int sd; struct sockaddr_in sa; sd = socket(AF_INET, SOCK_STREAM, 0); sa. sin_family

connect() example int sd; struct sockaddr_in sa; sd = socket(AF_INET, SOCK_STREAM, 0); sa. sin_family = AF_INET; sa. sin_port=htons(5100); sa. sin_addr. s_addr= htonl(inet_addr(“ 128. 226. 123. 101”)); if(connect(sd, (struct sockaddr *) &sa, sizeof(sa))!= -1) { …}

Sending and Receiving – talk to me! int recv(int sockfd, void *buff, size_t mbytes,

Sending and Receiving – talk to me! int recv(int sockfd, void *buff, size_t mbytes, int flags); int send(int sockfd, void *buff, size_t mbytes, int flags);

UDP Client-Server socket() bind() “well-known” port Client recvfrom() socket() (Block until receive datagram) Data

UDP Client-Server socket() bind() “well-known” port Client recvfrom() socket() (Block until receive datagram) Data (request) sendto() recvfrom() Data (reply) - No “handshake” - No simultaneous close - No fork() for concurrent servers! close()

Sending and Receiving int recvfrom(int sockfd, void *buff, size_t mbytes, int flags, struct sockaddr

Sending and Receiving int recvfrom(int sockfd, void *buff, size_t mbytes, int flags, struct sockaddr *from, socklen_t *addrlen); int sendto(int sockfd, void *buff, size_t mbytes, int flags, const struct sockaddr *to, socklen_t addrlen); Same as recv() and send() but for addr recvfrom fills in address of where packet came from sendto requires address of where sending packet to

getpeername()--Who are you? It will tell you who is at the other end of

getpeername()--Who are you? It will tell you who is at the other end of a connected stream socket. The synopsis: #include <sys/socket. h> int getpeername(int sockfd, struct sockaddr *addr, int *addrlen);

Gethostname() --Who am I? Returns the name of the computer that your program is

Gethostname() --Who am I? Returns the name of the computer that your program is running on. You can then use gethostbyname() to determine the IP address of your local machine. Here's the breakdown: #include <unistd. h> int gethostname(char *hostname, size_t size);

Example of Stream Server: echo /* stream server: echo what is received from client

Example of Stream Server: echo /* stream server: echo what is received from client */ #include <sys/types. h> #include <sys/socket. h> #include <netinet/in. h> #include <arpa/inet. h> #include <string. h> #include <unistd. h> #include <stdlib. h> #include <stdio. h> int main (int argc, char *argv[]) { int s, t, sinlen; struct sockaddr_in sin; char msg[80];

Example of Stream Server: echo (cont’d) if (argc < 2) { printf (”%s portn”,

Example of Stream Server: echo (cont’d) if (argc < 2) { printf (”%s portn”, argv[0] ); /* input error: need port no! */ return -1; } if ( (s = socket(AF_INET, SOCK_STREAM, 0 ) ) < 0) { /* create socket*/ perror(”socket”); /* socket error */ return -1; } sin_family = AF_INET; /*set protocol family to Internet */ sin_port = htons(atoi(argv[1])); /* set port no. */ sin_addr. s_addr = INADDR_ANY; /* set IP addr to any interface */ if (bind(s, (struct sockaddr *)&sin, sizeof(sin) ) < 0 ){ perror(”bind”); return -1; /* bind error */ }

Example of Stream Server: echo (cont’d) /* server indicates it’s ready, max. listen queue

Example of Stream Server: echo (cont’d) /* server indicates it’s ready, max. listen queue is 5 */ if (listen(s, 5)) { perror (”listen”); /* listen error*/ return -1; } sinlen = sizeof(sin); while (1) { /* accepting new connection request from client, socket id for the new connection is returned in t */ if ( (t = accept(s, (struct sockaddr *) &sin, &sinlen) ) < 0 ){ perror(”accept ”); /* accpet error */ return -1; }

Example of Stream Server: echo (cont’d) printf( ”From %s: %d. n”, inet_ntoa(sin. sin_addr), ntohs(sin.

Example of Stream Server: echo (cont’d) printf( ”From %s: %d. n”, inet_ntoa(sin. sin_addr), ntohs(sin. sin_port) ); if ( read(t, msg, sizeof(msg) ) <0) { /* read message from client */ perror(”read”); /* read error */ return -1; } if ( write(t, msg, strlen(msg) ) < 0 ) { /* echo message back */ perror(”write”); return -1; /* write error */ } /* close connection, clean up sockets */ if (close(t) < 0) { perror(”close”); return -1; } } // not reach below if (close(s) < 0) { perror(”close”); return -1; } return 0; }

Example of Stream Client: echo /* stream client: send a message to server */

Example of Stream Client: echo /* stream client: send a message to server */ #include <sys/types. h> #include <sys/socket. h> #include <netinet/in. h> #include <arpa/inet. h> #include <string. h> #include <unistd. h> #include <stdlib. h> #inlcude <stdio. h> #include <netdb. h> int main (int argc, char *argv[] ) { int s, n; struct sockaddr_in sin; struct hostent *hptr; char msg[80] = ”Hello World!”;

Example of Stream Client: echo if ( (cont’d) argc < 3 ) { printf

Example of Stream Client: echo if ( (cont’d) argc < 3 ) { printf ( ”%s host portn”, argv[0] ); /* input error: need host & port */ return -1; } if ( (s = socket(AF_INET, SOCK_STREAM, 0 ) ) < 0) { /* create socket*/ perror(”socket”); /* socket error */ return -1; } sin_family = AF_INET; /*set protocol family to Internet */ sin_port = htons(atoi(argv[2])); /* set port no. */ if ( (hptr = gethostbyname(argv[1]) ) == NULL){ fprintf(stderr, ”gethostname error: %s”, argv[1]); return = -1; } memcpy( &sin. sin_addr, hptr->h_length);

Example of Stream Client: echo if(cont’d) (connect (s, (struct sockaddr *)&sin, sizeof(sin) ) <

Example of Stream Client: echo if(cont’d) (connect (s, (struct sockaddr *)&sin, sizeof(sin) ) < 0 ){ perror(”connect”); return -1; /* connect error */ } if ( write(s, msg, strlen(msg) +1) < 0 ) { /* send message to server */ perror(”write”); return -1; /* write error */ } if ( ( n = read(s, msg, sizeof(msg) ) ) <0) { /* read message from server */ perror(”read”); return -1; /* read error */ } printf (” %d bytes: %sn”, n, msg); /* print message to screen */ /* close connection, clean up socket */ if (close(s) < 0) { perror(”close”); /* close error */ return -1; } return 0; }

Compiling and Executing garnet% g++ -o echo-server. c -lsocket -lnsl garnet% g++ -o echo-client.

Compiling and Executing garnet% g++ -o echo-server. c -lsocket -lnsl garnet% g++ -o echo-client. c -lsocket -lnsl garnet% echo-server 5700 & garnet% echo-client opal 5700 From 128. 226. 123. 110: 32938. 12 bytes: Hello World!

Concurrent Servers Receive blocks; how do servers that support multiple clients work? Threaded servers;

Concurrent Servers Receive blocks; how do servers that support multiple clients work? Threaded servers; only a thread blocks Asynchronous receive; receive that doesn’t block Select() system call lets you test which sockets have something ready to receive so that you are guaranteed not to block Examples next time/on class webpage

select #include <sys/select. h> #include <sys/time. h> int select ( int numfds, fd_set *readfds,

select #include <sys/select. h> #include <sys/time. h> int select ( int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); Struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ }

select Void FD_ZERO(fd_set *set) ; Void FD_SET(int fd, fd_set *set) ; Turn on the

select Void FD_ZERO(fd_set *set) ; Void FD_SET(int fd, fd_set *set) ; Turn on the bit for fd in fdset Void FD_CLR(int fd, fd_set *set) ; Clear all bits in fdset. Turn off the bit for fd in fdset Int FD_ISSET(int fd, fd_set *set) ; Is the bit for fd on in fdset?

Select example #include <sys/time. h> #include <sys/types. h> #include <unistd. h> #define STDIN 0

Select example #include <sys/time. h> #include <sys/types. h> #include <unistd. h> #define STDIN 0 /* file descriptor for standard input */ main() { struct timeval tv; fd_set readfds; tv. tv_sec = 2; tv. tv_usec = 500000; FD_ZERO(&readfds); FD_SET(STDIN, &readfds); /* don't care about writefds and exceptfds: */ select(STDIN+1, &readfds, NULL, &tv); if (FD_ISSET(STDIN, &readfds)) printf("A key was pressed!n"); else printf("Timed out. n"); }

Extra stuff – probably not interesting

Extra stuff – probably not interesting

Socket Options setsockopt(), getsockopt() SO_LINGER SO_RCVBUF, SO_SNDBUF upon close, discard data or block until

Socket Options setsockopt(), getsockopt() SO_LINGER SO_RCVBUF, SO_SNDBUF upon close, discard data or block until sent change buffer sizes for TCP is “pipeline”, for UDP is “discard” SO_RCVTIMEO, SO_SNDTIMEO timeouts

Socket Options (TCP) TCP_KEEPALIVE TCP_MAXRT idle time before close (2 hours, default) set timeout

Socket Options (TCP) TCP_KEEPALIVE TCP_MAXRT idle time before close (2 hours, default) set timeout value TCP_NODELAY disable Nagle Algorithm

fcntl() ‘File control’ but used for sockets, too Signal driven sockets Set socket owner

fcntl() ‘File control’ but used for sockets, too Signal driven sockets Set socket owner Get socket owner Set socket non-blocking flags = fcntl(sockfd, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(sockfd, F_SETFL, flags); Beware not getting flags before setting!