210 likes | 474 Vues
ADVANCED NETWORK PROGRAMMING. ADVANCED SOCKET OPTIONS IPv4&IPv6 Interoperability IOCTL Options Advanced I/O Functions Nonblocking I/O Functions Thrads Client&Server Design Alternatives. BİLGİN METİN. IPv4&IPv6 Interoperability.
E N D
ADVANCED NETWORK PROGRAMMING • ADVANCED SOCKET OPTIONS • IPv4&IPv6 Interoperability • IOCTL Options • Advanced I/O Functions • Nonblocking I/O Functions • Thrads • Client&Server Design Alternatives BİLGİN METİN
IPv4&IPv6 Interoperability • Over the coming years there will probably be a gradual transition of the internet from IPv4 to IPv6. • During this transition phase, it is important that existing IPv4 applications continue to work with newer IPv6 applications.
IPv4&IPv6 Interoperability IPv4 client and IPv6 server TCP UDP IPv4 IPv6 IPv4 IPv6 IPv4 mapped IPv4 IPv6 IPv4 mapped IPv4 IPv6 An IPv4 socket can always be changed to IPv6 socket. Any IPv4 address already associated with the socket are converted to IPv4 mapped IPv6 address
IPv4&IPv6 Interoperability IPv4 server and IPv6 client TCP UDP IPv4 IPv6 IPv4 IPv6 IPv4 mapped IPv4 IPv6 IPv4 mapped IPv4 IPv6 An IPv6 socket can be changed to IPv4 socket only if its address already associated with the socket is IPv4 mapped IPv6 address
IPv4&IPv6 Interoperability Int af; socklen_t clilen; Struct sockaddr_in6 cli; Struct hostent *ptr; af=AF_INET6; setsockopt(STDIN_FILENO, IPPROTOv6, IPV6_ADDRFORM, &af , sizeof(af)); clien=sizeof(cli); getpeername(0, &cli, &clilen); Ptr=gethostbyaddr(&cli, sinb_addr, 16 , AF_INET6);
IOCTL Options • The IOCTL function has traditionally been the system interface used for everything that did not put into some nice defined category. • Possix is geting rid of IOCTL by creating specific wrapper functions. • Nevertheless numerous functions remain for obtaining the interface information, accessing the route table and the arp cache for example. İnt ioctl(int fd, int request, ... , *argument); Some important request options • FIONBIO : The nonblocking flag is cleared or turned on depending on third argument (zero or non-zero) • FIONREAD: Return in the integer pointed to by third argument to ioctl, the number of bytes currently in the socket receive buffer.
IOCTL Options #include "unp.h" #include <net/if_arp.h> int main(int argc, char **argv) { int family, sockfd; char str[INET6_ADDRSTRLEN]; char **pptr; unsigned char *ptr; struct arpreq arpreq; struct sockaddr_in *sin; pptr = my_addrs(&family); for ( ; *pptr != NULL; pptr++) { printf("%s: ", Inet_ntop(family, *pptr, str, sizeof(str))); switch (family) { case AF_INET: sockfd = Socket(AF_INET, SOCK_DGRAM, 0); sin = (struct sockaddr_in *) &arpreq.arp_pa; bzero(sin, sizeof(struct sockaddr_in)); sin->sin_family = AF_INET; memcpy(&sin->sin_addr, *pptr, sizeof(struct in_addr)); Ioctl(sockfd, SIOCGARP, &arpreq); ptr = &arpreq.arp_ha.sa_data[0]; printf("%x:%x:%x:%x:%x:%x\n", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)); break; default: err_quit("unsupported address family: %d", family); }} exit(0); }
Advanced I/O Functions • Socket timeouts. • Alarm • Select • SO_RCVTIMEO and SO_SNDTIMEO • Variations of the read and write functions. • Recv and send • Readv and writev • Recvmsg and sendmsg • How to determine how much data is in the socket buffer. • ioctl with FIONREAD parameter • MSG_PEEK option with recv and send functions
Advanced I/O Functions #include "unp.h" /* connect_timeo */ static void connect_alarm(int); int connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec) { Sigfunc *sigfunc; int n; sigfunc = Signal(SIGALRM, connect_alarm); if (alarm(nsec) != 0) err_msg("connect_timeo: alarm was already set"); if ( (n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0) { close(sockfd); if (errno == EINTR) errno = ETIMEDOUT; } alarm(0); /* turn off the alarm */ Signal(SIGALRM, sigfunc); /* restore previous signal handler */ return(n); } static void connect_alarm(int signo) { return; /* just interrupt the connect() */ } void /* end connect_timeo */ Connect_timeo(int fd, const SA *sa, socklen_t salen, int sec) { if (connect_timeo(fd, sa, salen, sec) < 0) err_sys("connect_timeo error"); }
NONBLOCKING I/O • By default sockets are blocking • We can divide the socket calls that may block into for categories • Input Operations • Output operations • Accept • Inıtiating outgoing connections
NONBLOCKING I/O #include <stdio.h> /* STR_CLI */ #define MAXLINE 512 str_cli(fp, sockfd) register FILE *fp; register int sockfd; { int n; char sendline[MAXLINE], recvline[MAXLINE + 1]; while (fgets(sendline, MAXLINE, fp) != NULL) { n = strlen(sendline); if (writen(sockfd, sendline, n) != n) err_sys("str_cli: writen error on socket"); /* Now read a line from the socket and write it to stdr out*/ n = readline(sockfd, recvline, MAXLINE); if (n < 0) err_dump("str_cli: readline error"); recvline[n] = 0; /* null terminate */ fputs(recvline, stdout); } if (ferror(fp)) err_sys("str_cli: error reading file"); }
NONBLOCKING I/O parent stdin SERVER fork stdout child CLIENT
NONBLOCKING I/O #include "unp.h“ /* STR_CLI FUNTION USING FORK */ void str_cli(FILE *fp, int sockfd) { pid_t pid; char sendline[MAXLINE], recvline[MAXLINE]; if ( (pid = Fork()) == 0) { /* child: server -> stdout */ while (Readline(sockfd, recvline, MAXLINE) > 0) Fputs(recvline, stdout); kill(getppid(), SIGTERM); /* in case parent still running */ exit(0); } /* parent: stdin -> server */ while (Fgets(sendline, MAXLINE, fp) != NULL) Writen(sockfd, sendline, strlen(sendline)); Shutdown(sockfd, SHUT_WR); /* EOF on stdin, send FIN */ pause(); return; }
THREADS • FORK works well... In traditional UNIX model, when a process needs something performed by Another entity, it forks a child process and lets the child perform the processing. • But fork is expensive! • Memory is copied from the parent to the child • IPC is required to pass information between the parent and child after the fork Threads help with both problem: • Thread creation can be 10 or 100 times faster than process creation. • All threads within a process share the same global memory
THREADS Copyto Thread stdin SERVER Pthread_create Main( ) Thread stdout CLIENT
THREADS #include "unpthread.h" void *copyto(void *); static int sockfd; /* global for both threads to access */ static FILE *fp; void str_cli(FILE *fp_arg, int sockfd_arg) { char recvline[MAXLINE]; pthread_t tid; sockfd = sockfd_arg; /* copy arguments to externals */ fp = fp_arg; Pthread_create(&tid, NULL, copyto, NULL); while (Readline(sockfd, recvline, MAXLINE) > 0) Fputs(recvline, stdout); } void * copyto(void *arg) { char sendline[MAXLINE]; while (Fgets(sendline, MAXLINE, fp) != NULL) Writen(sockfd, sendline, strlen(sendline)); Shutdown(sockfd, SHUT_WR); /* EOF on stdin, send FIN */ return(NULL); /* 4return (i.e., thread terminates) when end-of-file on stdin */ }
CLIENT&SERVER DESIGN ALTERNATIVES Traditional Approaches • Iterative Server • Concurrent Server • Select option • Concurrent Servers with threads Modern Approaches • Preforking Concurrent Server • Prethreading concurrent server
CLIENT-SERVER DESIGN ALTERNATIVES • If the server is not heavily used, traditional concurrent server model, with one fork per client is fine. • Preforking and Prethreading Concurrent server approach reduces process control CPU time compared to the traditional one by a factor of 10 or more.
ADVANCED NETWORK PROGRAMMING • ADVANCED SOCKET OPTIONS • IPv4&IPv6 Interoperability • IOCTL Options • Advanced I/O Functions • Nonblocking I/O Functions • Thrads • Client&Server Design Alternatives