230 likes | 410 Views
Socket Programming Part 2. Sop, Fan 07302010028@fudan.edu.cn Reference: Daniel Spangenberger Computer Networks PPT-4 Socket Programming. Topics. Concurrency Review Why should we use …? Our experiences? Socket Programming related System requirement(robustness…)
E N D
Socket ProgrammingPart 2 Sop, Fan 07302010028@fudan.edu.cn Reference: Daniel Spangenberger Computer Networks PPT-4 Socket Programming
Topics • 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?
A scenario… Clients Server User 1 (goes to lunch) connect() accept() fgets() Blocks! read() User 2 connect() Blocked!
How did we add concurrency? • 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
Multi-process • Fork() • Use Pid to verify different process • Assign different task flow accordingly • Signal & waitpid(…) • Tracing child processes, kill the zombies • Other process control methods?
Multi-thread • pthread_create • Create thread according to detailed settings • Pthread(series: join, detach, cancel…) • Imply different polices. • Other thread control methods?
I/O Multiplexing • Monitor sockets with select() • int select(intmaxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const structtimespec *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
So what about bit vectors? • void FD_ZERO(fd_set *fdset); • Clears all the bits • void FD_SET(intfd, fd_set *fdset); • Sets the bit for fd • void FD_CLR(intfd, fd_set *fdset); • Clears the bit for fd • int FD_ISSET(intfd, fd_set *fdset); • Checks whether fd’s bit is set
Robustness? • Requirements • Mass users • User Experience • Incidents • Server/Network/Client breakdown? • Hacking? • …
What happened if…? Client(s) Server socket() socket() bind() listen() select() FD_ISSET(sfd) connect() accept() Hacking! Hacking!!! write() read() Server breakdown! read() write() Exceptions here! close() read() … check_clients() main loop close()
Solutions? • Socket API offers variable settings to meet different demands. (methods settings) • Programming concurrency with different detailed settings . • Exception/ error cases handling
Socket setting example • Address re-use • Non-blocking int sock, opts; sock = socket(…); // getting the current options setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opts, sizeof(opts)); // 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(…);
Server Example • An easy model.
Code – part 1 structsockaddr_insaddr, caddr; intsockfd, 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, (structsockaddr *) &saddr, sizeof(saddr))) printf(“Error binding\n”); if (listen(sockfd, 5) < 0) { // listen for incoming connections printf(“Error listening\n”); clen = sizeof(caddr)
Code – part 2 // 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, (structsockaddr *) &caddr, &clen))) printf(“Error accepting\n”); add_client(isock, &caddr, &pool); } check_clients(&pool); } // close it up down here
Change to an IRC server? • Your suggestions?
Internet Relay Chat Network Architecture
What was pool? • A struct something like this: typedefstructs_pool { intmaxfd; // largest descriptor in sets fd_setread_set; // all active read descriptors fd_setwrite_set; // all active write descriptors fd_setready_set; // descriptors ready for reading intnready; // return of select() intclientfd[FD_SETSIZE]; // max index in client array // might want to write this read_bufclient_read_buf[FD_SETSIZE]; // what else might be helpful for project 1? } pool;
Commands to Implement • Basic Commands • NICK • USER • QUIT • Channel Commands • JOIN • PART • LIST • Advanced Commands • PRIVMSG • WHO
Back to that lifecycle… Client(s) Server socket() socket() bind() listen() select() FD_ISSET(sfd) connect() Connection Request accept() write() read() Client / Server Session(s) read() write() close() EOF read() check_clients() main loop close()
Suggestions • 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
Project related • 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