====== Socket ====== ===== Basic socket programming ===== ===== Select() - multiplexing ===== ===== Handle Brocken pipe ===== socket level.. request level.. process level (handle signal). ==== SO_NOSIGPIPE ==== not available in Fedora 16. don't knwo why. ==== MSG_NOSIGNAL ==== Using send() with flag MSG_NOSIGNAL to prevent send() from emitting SIGPIPE in case peer broke dring writing. In that case, send() will return -1 and errno is set to EPIPE. ** attention ** when using strerror(errno) to read errno, #include must be available. Otherwise, client will crashed wit segfault. ==== Handle signal ==== static inline void suppress_sigpipe(void) { #if ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE) /* We want to ignore possible SIGPIPE that we can generate on write. SIGPIPE is delivered *synchronously* and *only* to the thread doing the write. So if it is reported as already pending (which means the thread blocks it), then we do nothing: if we generate SIGPIPE, it will be merged with the pending one (there's no queuing), and that suits us well. If it is not pending, we block it in this thread (and we avoid changing signal action, because it is per-process). */ sigset_t pending; sigpending(&pending); control.sigpipe_pending = sigismember(&pending, SIGPIPE); if (! control.sigpipe_pending) { sigset_t blocked; pthread_sigmask(SIG_BLOCK, &config.sigpipe_mask, &blocked); /* Maybe is was blocked already? */ control.sigpipe_unblock = ! sigismember(&blocked, SIGPIPE); } #endif /* ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE) */ } static inline void restore_sigpipe(void) { #if ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE) /* If SIGPIPE was pending already we do nothing. Otherwise, if it become pending (i.e., we generated it), then we sigwait() it (thus clearing pending status). Then we unblock SIGPIPE, but only if it were us who blocked it. */ if (! control.sigpipe_pending) { sigset_t pending; sigpending(&pending); if (sigismember(&pending, SIGPIPE)) { /* Protect ourselves from a situation when SIGPIPE was sent by the user to the whole process, and was delivered to other thread before we had a chance to wait for it. */ static const struct timespec nowait = { 0, 0 }; RESTART(sigtimedwait(&config.sigpipe_mask, NULL, &nowait)); } if (control.sigpipe_unblock) pthread_sigmask(SIG_UNBLOCK, &config.sigpipe_mask, NULL); } #endif /* ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE) */ } ===== Useful linux command ===== ==== child/parent processes ==== * ps aux | grep * pstree * ps --ppid * ps --forest -ef ==== socket info ==== * ipcs * netstat -vaun see open ports & processes * lsof -i display list of open ports * lsof -i 4 -a -p 9255 display all open IPv4 network files in use by the process whose PID is 9255 ===== Sources ===== * http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#twotypes * http://daniel.haxx.se/projects/portability/ * http://stackoverflow.com/questions/108183/how-to-prevent-sigpipes-or-handle-them-properly * http://tldp.org/LDP/lpg/node8.html#SECTION00710000000000000000 * layer 2,3 sockets: http://aschauf.landshut.org/fh/linux/udp_vs_raw/ch01.html * message handling: * http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.hala001/stms.htm * http://gamedevcoder.wordpress.com/2011/01/14/non-blocking-sending-and-receiving-data-via-tcp/ * sending struct over network: * http://stackoverflow.com/questions/8000851/passing-a-struct-over-tcp-sock-stream-socket-in-c ====== Portable Socket ====== {{tag>cpp socket}} ===== Sources ===== * http://long.ccaba.upc.edu/long/045Guidelines/eva/ipv6.html