您的位置:首页 > 理论基础 > 计算机网络

《Unix网络编程》卷1:套接字联网API(第3版):广播、多播、信号驱动I/O、线程

2017-08-26 23:33 344 查看
全书共31章+附录。

计划安排:从第19章开始内容更深入,逐渐看不懂,故后续章节精简。
时间安排:计划时间1.5个月 == 6个周末 == 12个自然日。
2017.08.05    第01-03章:TCP/IP简介、传输层、套接字编程简介
2017.08.06    第04-06章:基本TCP编程、TCP客户端/服务器程序、I/O复用
2017.08.12    第07-09章:套接字选项、基本UDP编程、基本SCTP编程
2017.08.13    第10-12章:SCTP客户端/服务器程序例子、名字与地址互换、IPv4和IPv6互操作性
2017.08.19    第13-15章:守护进程和inetd超级服务器、高级I/O、Unix域协议
2017.08.20    第16-18章:非阻塞I/O、ioctl操作、路由套接字

2017.08.26    第19-27章:广播、多播、信号驱动I/O、线程、tcpdump

>>第19章丶密钥管理套接字

此章内容略。(目前的基础很难读懂)

>>第20章丶广播

单播:一个进程就与另一个进程通信。TCP只支持单播寻址。



图解要点:

(1) 多播支持在IPv4中是可选的,在IPv6中是必需的;

(2) IPv6不支持广播。使用广播的任何IPv4程序一旦移植到IPv6就必须改用多播重新编写;

(3) 广播和多播要求用于UDP或原始IP,它们不能用于TCP。

ARP,地址解析协议。IPv4的基本组成部分之一。使用链路层广播而不是IP层广播。ARP的广播请求为:IP地址为a.b.c.d的系统两名身份,告诉我你的硬件地址。

DHCP,动态主机配置协议。

NTP,网络时间协议。

路由守护进程,routed是最早实现且最常用的路由守护进程之一,它在一个局域网上广播自己的路由表。

SIGALRM信号引起的竞争状态,使用alarm函数和SIGALARM信号是对读操作设置超时的一个常用办法,这个微秒的错误在网络应用程序中比较常见,有三个正确的解决办法:

(1) 使用pselect;

(2) 使用sigsetjmp和siglongjmp

(3) 使用从信号处理函数到主循环的IPC(典型为管道)

>>第21章丶多播

单播地址标识单个IP接口;

广播地址标识某个子网的所有IP接口;一般用于局域网。

多播地址标识一组IP接口,既可用在局域网也可以跨广域网。

>>第25章丶信号驱动式I/O

信号驱动式I/O是指:进程预先告知内核,使得当某个描述符上发生某事时,内核使用信号通知相关进程。曾被称作异步I/O,但不是真正的异步I/O。

套接字的信号驱动式I/O要求进程执行以下3个步骤:

(1) 建立SIGIO信号的信号处理函数;

(2) 设置该套接字的属主,通常使用fcntl的F_SETOWN命令设置;

(3) 开启该套接字的信号驱动式I/O,通常通过使用fcntl的F_SETFL命令打开O_ASYNC标志完成。

>>第26章丶线程

并发服务器程序中,父进程accept一个连接,fork一个子进程,该子进程处理与该连接对端的客户之间的通信。

但该fork调用却存在一些问题:

(1) fork是昂贵的,fork要把父进程的内存映像复制到子进程,并在子进程中复制所有描述符。

(2) fork返回之后父进程之间信息的传递需要进程间通信IPC机制。

同一进程内的所有线程除了共享全局变量外还共享:

进程指令、大多数数据、打开的文件描述符、信号处理函数和信号处置、当前工作目录、用户ID和组ID。

每个线程有各自的:线程ID、寄存器集合、栈、errno、信号掩码、优先级。

线程创建

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

Compile and link with -pthread.

// pthread_create相当于进程的fork

每个线程都有许多属性(attribute):优先级、初识栈大小、是否应该成为一个守护线程等。

可以在创建线程时通过初始化一个取代默认设置的 phtread_attr_t 变量指定这些属性。

通常情况下我们采用默认设置时,把attr参数指定为空指针。

线程终止

#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);

Compile and link with -pthread.

// pthread_join相当于进程的waitpid

// 如果本线程未曾脱离,它的线程ID和退出状态将一直留存到调用进程内的某个其他线程对它调用pthread_join

#include <pthread.h>

int pthread_detach(pthread_t thread);

Compile and link with -pthread.

// 如果一个线程需要知道另一个线程什么时候终止,那就最好保持第二个线程的可汇合状态。

#include <pthread.h>

void pthread_exit(void *retval);

Compile and link with -pthread.

线程ID

#include <pthread.h>

pthread_t pthread_self(void);

Compile and link with -pthread.

// pthread_self相当于进程的getpid

互斥锁

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

条件变量

#include <pthread.h>

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

int pthread_cond_signal(pthread_cond_t *cond);

// 等待wait和唤醒signal相应条件变量上的单个线程

int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);

int pthread_cond_broadcast(pthread_cond_t *cond);

// 一个线程唤醒多个线程需要使用broadcast

【调试测试小程序】

tcpdump

一边从网络读入分组一边显示关于这些分组的大量信息

$ tcpdump '(udp and port daytime) or icmp'

// 只显示所指定的准则匹配的那些分组

$ tcpdump 'tcp and port 80 and tcp[13:1] & 2 !=0'

// 只显示源端口或目的端口为13的UDP数据报亦或ICMP分组

$ tcpdump 'tcp and tcp[0:2] > 7000 and tcp[0:2] <= 7005'

// 只显示源端口或目的端口为80切设置了SYN标志的TCP分节。

2017.08.26

全书基本完... (除去部分更深入的内容,后续有需要时作为资料翻阅)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络编程
相关文章推荐