socket()
bind()
listen() ———-blocked <—-unblock SYN i connect() ———>ACK i+1, SYN j
accept()———-blocked <——unblock ACK j+13-way hand-shake
socket(*.21, *.*) — listening socket
accept() returns new socket (server_addr, 21, client_addr.client.port)
tcp write —- blocked until the buffer in APP have already been copied to the buffer in KERNEL
when the buffer in KERNEL is out of free space, APP be suspended.
data resident in the KERNEL buffer until its ACK has been received.
common [sockaddr] struct and [sockaddr_in]
struct sockaddr{ uint8_t sa_len; sa_family_t sa_family; char sa_data[14]; } struct sockaddr_in{ //IPv4 socket address struct }new generic socket address struct for IPv6
struct sockaddr_storage { uint8_t ss_len; /* length of this struct (implementation dependent) */ sa_family_t ss_family; /* address family: AF_xxx value */ /* implementation-dependent elements to provide: * a) alignment sufficient to fulfill the alignment requirements of * all socket address types that the system supports. * b) enough storage to hold any type of socket address that the * system supports. */ };
[wait] and [waitpid] function
#include <sys/wait.h> pid_t wait (int *statloc); pid_t waitpid (pid_t pid, int *statloc, int options);wait: clean a terminated thread and returns its thread id and exit status
when all child threads are executing, blocked until anyone terminates
waitpid: waitpid gives us more control over which process to wait for and whether or not to block. First, the pid argument lets us specify the process ID that we want to wait for. A value of -1 says to wait for the first of our children to terminate. (There are other options, dealing with process group IDs, but we do not need them in this text.) The options argument lets us specify additional options. The most common option is WNOHANG. This option tells the kernel not to block if there are no terminated children.
notice: SIGCHLD is not queued.
the most proper way to handle zombie child threads are using waitpid with options WNOHANG as below :
#include "unp.h" void sig_chld(int signo) { pid_t pid; int stat; while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) printf("child %d terminated\n", pid); return; } |
notice: slow system calls such as, accept() read() write() connect(), may be interrupted by signal handling, and return EINTR, we must handle them by redoing them.

One Response
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.
very nice material