《TCP/IP网络编程》 阅读笔记(三)

95 阅读4分钟

基于TCP的半关闭

半关闭指的是可以传输数据但无法接收,或可以接收数据但无法传输。顾名思义就是关闭流的一半。

优雅断开的shutdown函数

shutdown函数用来关闭其中一个流

#include<sys/socket.h>
int shutdown(int sock,int howto);
//成功时返回0,失败时返回-1
sock 需要断开时的套接字文件描述符 
howto 传递断开方式信息
    - SHUT_RD 断开输入流 
    - SHUT_WR 断开输出流 如果输出缓冲还有未传输的数据,则将传递至目标主机
    - SHUT_RDWR 断开IO流

利用域名 获取 IP地址

#include<netdb.h>
struct hostent *gethostbyname(const char *hostname);
// 成功时返回hostent结构体地址,失败时返回NULL指针

struct hostent 
{
    char * h_name; // 存有官方域名
    char ** h_aliases;// 多个域名访问同一主页 ,同一IP可以绑定多个域名。
    int h_addrtype; // 存有IP地址的地址族信息   IPv4 or IPv6
    int h_length; //   IP地址长度  IPv4 4个字节, IPv6 ,16个字节
    char **h_addr_list; // 通过整数形式 保存域名对应的IP地址。用户较多的网站有可能分配多个IP地址给同一个域名,然后利用多个服务器进行负载均衡。 
}

利用IP地址 获取 域名

#include<netdb.h>
struct hostent *gethostbyaddr(const char *addr,socklen_t len,int family)
成功时 返回hostent结构体变量地址,失败时返回NULL 指针 

image.png

Time_wait

Time_wait 状态,不管是在服务器还是在客户端,先断开连接的套接字必然会经过Time-wait状态。但无需考虑客户端的Time-wait状态,因为客户端套接字的端口号是任意指定的。客户端每次运行程序都会动态分配端口号

并发服务器的实验方法

  1. 多进程服务器 : 通过创建多个进程提供服务
  2. 多路复用服务器:通过捆绑并统一管理I/O对象提供服务
  3. 多线程服务器:通过生成与客户端等量的线程提供服务

通过调用fork创建进程

#include<unistd.h>
pid_t fork(void):
// 成功时返回进程ID,失败时返回-1

fork函数将创建调用的进程副本,即复制正在运行的、调用fork函数的进程。但正是因为通过同一个进程,复制相同的内存空间,在因此之后的程序流要根据fork函数的返回值加以区分

  1. 父进程: fork函数返回子进程ID
  2. 子进程: fork函数返回0

僵尸进程

我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

销毁僵尸进程1: 利用wait函数

#include<sys/wait.h>  
pid_t wait(int *staloc);
-> 成功时返回子进程ID,失败时返回-1.

调用wait函数时

销毁僵尸进程2:使用waitpid函数

#include<sys/wait.h>
pid_t waitpid(pid_t pid,int *statloc, int options);
// 成功时返回终止的子进程ID(或0),失败时返回-1

image.png

信号处理

目的利用操作系统来通知父进程去回收子进程

信号与signal函数

下列函数为: 信号注册函数

# include<signal.h>
void (*signal(int signo,void (* func)(int))) (int);
// 为了在产生信号时调用,返回之前注册地函数指针。
函数名: signal 
参数: int signo,void(*func) (int)
返回类型: 参数为int 型,返回void型函数指针
1.参数1(signo)特殊情况信息 
2.参数2()特殊情况下要调用地函数的地址值

image.png

利用sigaction进行信号处理

#include<signal.h>
int sigaction(int signo,const struct sigaction *act,struct sigaction *oldact);
//成功时返回0,失败时返回-1 

image.png

基于多任务的并发处理器

  1. 基于进程的并发服务器模型

image.png