Sop, Fan 07302010028@fudan.edu.cn Reference: Daniel Spangenberger Computer Networks PPT-4 Socket Programming Concurrency Review Why should we use …? Our experiences? Socket Programming related System requirement(robustness…) How to cooperate with socket API? Example How to modify the example to fit further requirement? Clients User 1 Server connect() accept() fgets() (goes to lunch) Blocks! read() User 2 connect() Blocked! Processes Uses fork() Easy to understand(actually we have implemented one version!) A lot to consider about causing complexity(zombie, syscall…) Threads Natural concurrency (new thread per connection) Easier to understand (you know it already) Complexity is increased (possible race conditions) Use non-blocking I/O Uses select() Explicit control flow (no race conditions!) Explicit control flow more complicated though Fork() Use Pid to verify different process Assign different task flow accordingly Signal & waitpid(…) Tracing child processes, kill the zombies Other process control methods? pthread_create Create thread according to detailed settings Pthread(series: join, detach, cancel…) Imply different polices. Other thread control methods? Monitor sockets with select() int select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout); So what’s an fd_set? Bit vector with FD_SETSIZE bits maxfd – Max file descriptor + 1 readfs – Bit vector of read descriptors to monitor writefds – Bit vector of write descriptors to monitor exceptfds – Read the manpage, set to NULL timeout – How long to wait with no activity before returning, NULL for eternity void FD_ZERO(fd_set *fdset); Clears all the bits void FD_SET(int fd, fd_set *fdset); Sets the bit for fd void FD_CLR(int fd, fd_set *fdset); Clears the bit for fd int FD_ISSET(int fd, fd_set *fdset); Checks whether fd’s bit is set Requirements Mass users User Experience Incidents Server/Network/Client breakdown? Hacking? … Client(s) socket() Server socket() bind() listen() select() connect() FD_ISSET(sfd) accept() Hacking! Hacking!!! write() read() Server breakdown! read() write() Exceptions here! close() check_clients() main loop read() close() … Socket API offers variable settings to meet different demands. (methods settings) Programming concurrency with different detailed settings . Exception/ error cases handling Address re-use int sock, opts; sock = socket(…); // getting the current options setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opts, sizeof(opts)); Non-blocking // getting current options if (0 > (opts = fcntl(sock, F_GETFL))) printf(“Error…\n”); // modifying and applying opts = (opts | O_NONBLOCK); if (fcntl(sock, F_SETFL, opts)) printf(“Error…\n”); bind(…); An easy model. struct sockaddr_in saddr, caddr; int sockfd, clen, isock; unsigned short port = 80; if (0 > (sockfd=socket(AF_INET, SOCK_STREAM, 0))) printf(“Error creating socket\n”); memset(&saddr, '\0', sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(port); if (0 > (bind(sockfd, (struct sockaddr *) &saddr, sizeof(saddr))) printf(“Error binding\n”); if (listen(sockfd, 5) < 0) { // listen for incoming connections printf(“Error listening\n”); clen = sizeof(caddr) // Setup your read_set with FD_ZERO and the server socket descriptor while (1) { pool.ready_set = &pool.read_set; pool.nready = select(pool.maxfd+1, &pool.ready_set, &pool.write_set, NULL, NULL); if (FD_ISSET(sockfd, &pool.ready_set)) { if (0 > (isock = accept(sockfd, (struct sockaddr *) &caddr, &clen))) printf(“Error accepting\n”); add_client(isock, &caddr, &pool); } check_clients(&pool); } // close it up down here Your suggestions? Architecture A struct something like this: typedef struct s_pool { int maxfd; fd_set read_set; fd_set write_set; fd_set ready_set; int nready; // // // // // int clientfd[FD_SETSIZE]; largest descriptor in sets all active read descriptors all active write descriptors descriptors ready for reading return of select() // max index in client array // might want to write this read_buf client_read_buf[FD_SETSIZE]; // what else might be helpful for project 1? } pool; Basic Commands NICK USER QUIT Channel Commands JOIN PART LIST Advanced Commands PRIVMSG WHO Client(s) socket() Server socket() bind() listen() connect() Connection Request select() FD_ISSET(sfd) accept() write() read() read() Client / Server Session(s) close() check_clients() main loop EOF write() read() close() Strong I/O skills will be a great assistant. Read more about this field if interested Books as ‘UNIX Network Programming – The Sockets Networking API’ will be a good tutorial Deadline: 2011-4-10 Checkpoint: 2011-3-27 Detailed information will be put on the FTP: ftp://10.132.141.33/classes/08/102 计算机网络 /PROJECT/project 1