TCP/IP C 2 (TCP/IP Sockets in C 2/e, Morgan Kaufmann) (Michael J. Donahoo) (Kenneth L. Calvert) Chapter 06 Beyond Basic Socket Programming 6 6.1 6.2 6.3 6.4
6.5 6.6 / 2 (socket options)socket options) #include #include int setsockopt(int s, int level, int opt, const char *optval, int optlen); int getsockopt(int s, int level, int opt, const char *optval, int *len); s :
level : SOL_SOCKET: IPPROTO_IP: IP IPPROTO_TCP: TCP opt : optval : optlen : optval 3 Socket Option Layer level SOL_SOCKET IPPROTO_TCP TCP IPPROTO_IP IP 4
SOL_SOCKET Option name SO_BROADCAST: SO_DEBUG: DEBUG SO_REUSEADDR: SO_LINGER SO_KEEPALIVE: TCP keep-alive SO_OOBINLINE: OOB SO_RCVBUF: SO_SNDBUF: 5
TCP Timer TCP Retransmission Timer TCP Persist Timer TCP Keepalive Timer TCP Time-Waited Timer 6 ) Socket buffer TCP, UDP TCP write() ACK write() / SO_SNDBUF
SO_RCVBUF / (3-way handshake) listen() connect() 7 ) Socket buffer int optval; int optlen = sizeof(optval); if(getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, (char *)&optval, &optlen) == SOCKET_ERROR) err_quit("getsockopt()"); printf(" = %d d \n", optval);n", optval); optval = 2; if(setsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF,
(char *)&optval, sizeof(optval)) == SOCKET_ERROR) err_quit("setsockopt()"); 8 ) SO_REUSEADDR IP IP bind() ( ) bind() fork() 9 ) SO_REUSEADDR serv_sock=socket(PF_INET, SOCK_STREAM, 0); optlen = sizeof(option); option = TRUE; // #define TRUE 1 setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
10 Socket Option Layer level SOL_SOCKET IPPROTO_IP IP IPPROTO_TCP TCP 11 IPPROTO_IP IP_TTL Time To Live IP_MULTICAST_TTL TTL IP_ADD_MEMBERSHIP
IP_DROP_MEMBERSHIP IP_MULTICAST_LOOP loopback IP_MULTICAST_IF 12 (socket options)Multicast) 1. . - UDP . - . - . 13 (socket options)Multicast) 2. (socket options)Routing) TTL(socket options)Time To Live) - . - TTL . TTL
. 14 (socket options)Multicast) 3. Sender Receiver. - Sender : - Receiver : , 4. Sender Receiver Sender Receiver UDP . UDP . TTL ( ). (ip_mreq ). .
( ). 15 (socket options)Broadcast) 1. . - UDP ( ). - UDP IP . - ( ). - ( ). 16 (socket options)Broadcast) 2. . - : 192.12.31.255 192 12 31
IP IP 192 12 xxx 31 255 address 255 address - : 255.255.255.255 255
255 255 17 Socket Option Layer level SOL_SOCKET IPPROTO_IP IP IPPROTO_TCP TCP 18 IPPROTO_TCP TCP_KEEPALIVE keep-alive
TCP_MAXSEG TCP MSSS( ) TCP_NODELAY Nagle 19 Nagle . 1. . 2. ACK . 20 Nagle . 1. : .( )
2. : (ACK ). 3. : Nagle . 21 TCP_NODELAY 1. Nagle Disable . 2. TCP Nagle . serv_sock=socket(PF_INET, SOCK_STREAM, 0); opt_val = TRUE; // #define TRUE 1 setsockopt(serv_sock, IPPROTO_TCP, TCP_NODELAY, &opt_val, sizeof(opt_val));
22 ? 2 , 2 Fork , thread TCP TCP fork Thread 23 fork(socket options)) fork(socket options))
( , , ) PC(program counter) fork() Process ID(PID) vs : (fork) : (forked) fork ( , ) => 24 fork(socket options)) example
#include #include pid_t fork(void); /* */ fork(socket options)) fork() process id(pid) fork() 0 -> -1 #include #include #include #include pid_t pid_t pid; pid; pid=fork(); pid=fork(); /* /* copy copy new
new process process */ */ if(pid==0){ if(pid==0){ /* /* new new process process code code here here */ */ }} else{ else{ /* /* parent parent code code here here */ */ }} 25
fork(socket options)) 26 fork(socket options)) pid_t processID; for (;;) { if(clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr, &clntLen)) < 0) DieWithError("accept() failed"); if ((processID = fork())<0) DieWithError("fork() failed"); else if (processID == 0) { /* : */ close(servSock); HandleTCPClient(clntSock); exit(0); } /* : */ } 27
Thread Thread ? semi process, light weight process thread fork Network Programming thread -> mutex 28 Process Thread 29 Pthread POSIX thread POSIX thread set
POSIX ? portable operating system interface UNIX OS API IEEE pthread pthread create() worker(thread) worker worker worker pthread_join() worker 30 Thread int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg); pthread_t thread
ID pthread_attr_t attr Set to NULL if default thread attributes are used. void * (socket options)*start_routine) pointer to the function to be threaded. Function has a single argument: pointer to void. void *arg pointer to argument of function 31 pthread example(socket options)) #include #include #include #define NUM_THREADS 5 void *PrintHello(void *threadid) { int tid;
tid = (int)threadid; printf("Hello World! It's me, thread #%d d!\n", optval);n", tid); pthread_exit(NULL); } int main(int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; int rc, t; for(t=0;t
In main: creating thread 2 Hello World! It's me, thread #1! Hello World! It's me, thread #2! In main: creating thread 3 In main: creating thread 4 Hello World! It's me, thread #3! Hello World! It's me, thread #4! 32 pthread(socket options)) 33 pthread(socket options)) #include pthread_t tid; void *do_thread(void *arg); for (;;) { if(clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr, &clntLen)) < 0) DieWithError("accept() failed"); if(pthread_create(&tid, NULL, do_thread, (void *)clntSock) < 0 )
DieWithError(thread create() failed); } void *do_thread(void *arg) { int csock; csock=(int)arg; HandleTcpClient(csock); pthread_exit(NULL); } 34 (socket options)Signal) ? Ex) ctrl + c, ctrl + z, H/W OS OS /usr/include/signal.h
/usr/include/bits/signum.h 35 /usr/include/bits/signal.h #define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt , ctrl + c */ #define SIGQUIT 3 /* quit */ #define SIGILL 4 /* illegal instruction (not reset when caught) */ #define SIGTRAP 5
/* trace trap (not reset when caught) */ #define SIGIOT 6 /* IOT instruction */ #define SIGABRT 6 /* used by abort, replace SIGIOT in the future */ #define SIGEMT 7 /* EMT instruction */ #define SIGFPE 8 /* floating point exception */ #define SIGKILL 9 /* kill (cannot be caught or ignored) */ #define SIGBUS 10
/* bus error */ #define SIGSEGV 11 /* segmentation violation */ #define SIGSYS 12 /* bad argument to system call */ #define SIGPIPE 13 /* write on a pipe with no one to read it */ #define SIGALRM 14 /* alarm clock */ #define SIGTERM 15 /* software termination signal from kill */ #if defined(__rtems__) #define SIGURG
16 /* urgent condition on IO channel */ #define SIGSTOP 17 /* sendable stop signal not from tty */ #define SIGTSTP 18 /* stop signal from tty */ #define SIGCONT 19 /* continue a stopped process */ #define SIGCHLD 20 /* to parent on child stop or exit */ #define SIGCLD 20 /* System V name for SIGCHLD */ #define SIGTTIN
21 /* to readers pgrp upon background tty read */ #define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ #define SIGIO 23 /* input/output possible signal */ #define SIGPOLL SIGIO /* System V name for SIGIO */ #define SIGWINCH 24 /* window changed */ #define SIGUSR1 25/* user defined signal 1 */ #define SIGUSR2 26/* user defined signal 2 */ 36
(socket options)signal handler) Name SIGINT SIGILL SIGKILL SIGSEGV SIGALRM SIGCHLD SIGTERM Default action Description
Quit Interrupt Dump Illegal instruction Quit Kill Dump Out of range addr Quit Alarm clock Ignore Child status change Quit Sw termination sent by kill 37 1. , OS 2. 3. OS 38
sigaction(socket options)) #include int sigaction(int signo, const struct sigaction *act, struct sigaction *oldact ); int signo: sigaction act: sigaction sigaction old: sigaction struct sigaction { void (*sa_handler)( int ); sigset_t sa_mask; int sa_flags; } /* */ /* */ /* */
39 sigaction(socket options)) /* SIGINT . . */ void handler(int sig); int main(){ struct sigaction act; act.sa_handler = handler; sigemptyset( &act.sa_mask ); act.sa_flags = 0; sigaction( SIGINT, &act, 0 ); /* */ /* */ /* */ /* SIGINT handler */ while(1) { printf("Hello World!\n", optval);n"); sleep(1); } } void handler(int sig) { printf(type of signal is %d d \n", optval);n, sig);
} 40 (socket options)SIGALM ) SIGALM ? alarm(int) int void timer(int sig) { puts(alarm!! \n", optval);n"); } exit(0); int main(int argc, char **argv) struct sigaction act; act.sa_handler=timer; sigemptyset(&act.sa_mask); act.sa_flags=0; { state=sigaction(SIGALRM, &act, 0);
alarm(5); while(1){ puts(wait"); } return 0; sleep(2); } 41 SIGCHLD SIGCHLD ? fork() , fork() PTP 42 wait(socket options)) vs waitpid(socket options)) wait() #include #include
pid_t wait(int * status) waitpid() WNOHANG (pending) SIGCHLD . waitpid #include #include pid_t waitpid(pid_t pid, int * status, int options) 43 sigaction void handler(int sig){ int pid; int status; while(1) { pid = waitpid( WAIT_ANY, &status, WNOHANG ); if ( pid < 0 ) { perror("waitpid"); break; } if ( pid == 0 )
break; } } int main(int argc, char *argv[]){ struct sigaction act; act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGCHLD, &act, 0); pid = fork(); } 44 I/O Client Server Hi.. Hi..
Hi.. Hi.. Whats up? Whats up? Not much!! Not much!! Anyway.. Anyway.. What are you doing? What are you doing? Ive just finished network programming assignments Ive just finished network
programming assignments 45 I/O send(socket options)) , ? Server Client Hi.. send( ) recv() Hi.. Hi.. recv() send( )
Hi.. Whats up? send( ) recv() Whats up? Not much!! recv() send( ) Not much!! Anyway.. send(
)send( recv() Anyway.. recv() What are you doing? What are you doing? ) Ive just finished network recv() programming assignments send( Ive just finished network ) programming assignments 46 recv(socket options)), send(socket options))
send() , recv() , , block send(socket options)), recv(socket options)) 47 Non Block
(polling) (Asynchronous I/O) ( ) I/O I/O SIGIO 48 vs blocking blocking block listen(),connect(), accept(), recv(), send(), read(), write(), recvfrom(), sendto(), close() I/O . blocking
49 vs Non-blocking block nonblocking . non-blocking ( ) . 50 Blocking I/O Model Applicati on recvfrom kernel system call
process blocks no datagram ready datagram ready copy datagram process datagram return OK copy complete 51 Nonblocking I/O Model Applicati on recvfrom recvfrom
recvfrom kernel system call EWOULDBLOCK system call EWOULDBLO CK system call no datagram ready no datagram ready datagram ready copy datagram return OK process
datagram copy complete 52 I/O EWOULDBLOCK(socket options)WSAEWOULDBLOC) non-blocking I/O Linux fcntl(sock_fd, F_SETFL, O_NONBLOCK); // linux Windows unsigned long nb_flag = 1; ioctlsocket(sock, FIONBIO, &nb_flag); // nb_flag = 0 off polling while (read(..) == EWOULDBLOCK) {}
53 I/O(socket options) ) SIGIO Polling I/O 1. sigaction() 2. fcntl() 3. fcntl() FASYNC I/O 54 select(socket options)) (socket options)Multiplexing) ? select()
vs : I/O , : I/O 55 I/O Multiplexing Model(socket options)Select) Applicati on select kernel system call no datagram ready
return readable system call datagram ready copy datagram process blocks recvfrom process blocks process datagram return OK copy complete 56 select(socket options))
select(socket options)) fd #include #include #include int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set struct timeval { Read, write *exceptfds, struct timeval fd+1 *timeout); int tv_sec; int tv_usec;}; read(recv) fds
write(send) fds 0 : timeout Select return -1 : error 0=> 1 : IO FD Null => blocking 57 select(socket options)) // macro FD_ZERO(fd_set *set) - FD_SET(int fd, fd_set *set) - fd set FD_CLR(int fd, fd_set *set) - fd set IO ,
main(void) { fd_set rfds; struct timeval tv; it retval; FD_ZERO(&rfds); FD_SET(0, &rfds); tv.tv_sec=5; tv.tv_usec=0; retval = select(1, &rfds, NULL, NULL, &tv); if(retval) printf(Data is available now.\n", optval);n); else printf(No data within 5 seconed.\n", optval);n); exit(0); } 58 Select(socket options)) Start loop select ?
N Y 0 flag 1 Socket readable? N Y 0 Loop end flag 1
59 Select(socket options)) FD_ISSET(int fd, fd_set *set) - fd set active int game_end; fd_set readOK; flag=1; while(1) { FD_ZERO(&readOK); FD_SET(0,&readOK); /* */ select(maxfd+1, (fd_set*)&readOK, NULL, NULL, NULL); if(FD_ISSET(0,&readOK)) { send(); if(game_end) break; } Loop ! if(FD_ISSET(sock, &readOK) { recv(sock, buf, sizeof(buf), 0); if(game_end) break;
} 60 ? LAN LAN . e.g.) 203.252.153.255 // 203.252.153.0 LAN e.g) 255.255.255.255 61 UDP /*
/* */ */ SOCKADDR_IN serv; SOCKADDR_IN serv; memset(&remoteaddr, memset(&remoteaddr, 0, 0, sizeof(remoteaddr)); sizeof(remoteaddr)); serv.sin_family = AF_INET; serv.sin_family = AF_INET; serv.sin_port serv.sin_port == htons(9000); htons(9000);
serv.sin_addr.s_addr serv.sin_addr.s_addr == htonl(INADDR_BROADCAST); htonl(INADDR_BROADCAST); /* /* */ */ int broadcastPerm = 1; int broadcastPerm = 1; if if (setsockopt(sock,SOL_SOCKET, (setsockopt(sock,SOL_SOCKET, SO_BROADCAST, SO_BROADCAST, $broadcastPerm, $broadcastPerm, sizeof(broadcastPerm))
< 0) sizeof(broadcastPerm)) < 0) 62