Linux网络编程之服务器

120 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 25 天,点击查看活动详情

一、并发服务器

多进程并发服务器:server.c

  1. Socket(); 创建 监听套接字 lfd
  2. Bind() 绑定地址结构 Strcut scokaddr_in addr;
  3. Listen();
  4. while (1)
{

	cfd = Accpet();			接收客户端连接请求。
	pid = fork();
	if (pid == 0){			子进程 read(cfd) --- 小-》大 --- write(cfd)

		close(lfd)		关闭用于建立连接的套接字 lfd

		read()
		小--大
		write()

	} else if (pid > 0) {	

		close(cfd);		关闭用于与客户端通信的套接字 cfd	
		contiue;
	}
}

  1. 子进程:

    close(lfd)

    read()

    小--大

    write()

  2. 父进程:

    close(cfd);

    注册信号捕捉函数: SIGCHLD

    在回调函数中, 完成子进程回收

    while (waitpid());

多线程并发服务器: server.c

  1. Socket(); 创建 监听套接字 lfd

  2. Bind() 绑定地址结构 Strcut scokaddr_in addr;

  3. Listen();

  4. while (1)

 {		

	cfd = Accept(lfd, );

	pthread_create(&tid, NULL, tfn, (void *)cfd);

	pthread_detach(tid);  				// pthead_join(tid, void **);  新线程---专用于回收子线程。
 }
  1. 子线程:

     void *tfn(void *arg) 
     {
     	// close(lfd)			不能关闭。 主线程要使用lfd
    
     	read(cfd)
    
     	小--大
    
     	write(cfd)
    
     	pthread_exit((void *)10);	
     }
    

二、TCP状态时序图

结合三次握手、四次挥手 理解记忆。

  1. 主动发起连接请求端: CLOSE -- 发送SYN -- SEND_SYN -- 接收 ACK、SYN -- SEND_SYN -- 发送 ACK -- ESTABLISHED(数据通信态)

  2. 主动关闭连接请求端: ESTABLISHED(数据通信态) -- 发送 FIN -- FIN_WAIT_1 -- 接收ACK -- FIN_WAIT_2(半关闭)

    -- 接收对端发送 FIN -- FIN_WAIT_2(半关闭)-- 回发ACK -- TIME_WAIT(只有主动关闭连接方,会经历该状态)

    -- 等 2MSL时长 -- CLOSE

  3. 被动接收连接请求端: CLOSE -- LISTEN -- 接收 SYN -- LISTEN -- 发送 ACK、SYN -- SYN_RCVD -- 接收ACK -- ESTABLISHED(数据通信态)

  4. 被动关闭连接请求端: ESTABLISHED(数据通信态) -- 接收 FIN -- ESTABLISHED(数据通信态) -- 发送ACK

    -- CLOSE_WAIT (说明对端【主动关闭连接端】处于半关闭状态) -- 发送FIN -- LAST_ACK -- 接收ACK -- CLOSE

TCP示意图 image.png

三、2MSL时长

一定出现在【主动关闭连接请求端】。 --- 对应 TIME_WAIT 状态。

保证,最后一个 ACK 能成功被对端接收。(等待期间,对端没收到我发的ACK,对端会再次发送FIN请求。)

四、端口复用

int opt = 1; // 设置端口复用。

setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt));

五、半关闭

通信双方中,只有一端关闭通信。 --- FIN_WAIT_2

close(cfd);

shutdown(int fd, int how);

how:

  • SHUT_RD 关读端

  • SHUT_WR 关写端

  • SHUT_RDWR 关读写

shutdown在关闭多个文件描述符应用的文件时,采用全关闭方法。close,只关闭一个。