TCP服务器的单进程、多进程实现

一、socket编程

在理解TCP服务器时,我们必须了解socket编程,在上篇博客中,我们知道在TCP/IP协议中,“IP地址+TCP端口号/UDP端口号”唯一标识网络通讯中的唯一一个进程,我们把“IP地址+端口号”就成为socket。

在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成 的socketpair就唯一标识一个连接。socket本身有“插座”的意思,因此用来描述网络连接的一对一关系。

二、socket地址数据类型及相关函数

IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址⽤sockaddr_in结构体表⽰,包括16位端口号和32位IP地址,IPv6地址⽤sockaddr_in6结构体表⽰,包括16位端口号、 128位IP地址和⼀些控制字段。
socket API是一层抽象的⽹网络编程接口,适⽤用于各种底层⽹网络协议,如IPv4、IPv6,以及UNIX Domain Socket。然⽽,各种网络协议的地址格式并不相同,如下图所示:
70
由上图可以看出:各种socket地址结构体的开头都是相同的,前16位表示整个结构体的长度(并不是所有UNIX的实现 都有长度字段,如Linux就没有),后16位表示地址类型。IPv4、IPv6和UNIXDomain Socket的地 址类型分别定义为常数AF_INET、AF_INET6、AF_UNIX。这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的 内容。因此,socket API可以接受各种类型的sockaddr结构体指针做参数,例如bind、accept、connect等函数,这些函数的参数应该设计成void 类型以便接受各种类型的指针,但是sock API的实现早于ANSI C标准化,那时还没有void 类型,因此这些函数的参数都用struct sockaddr *类型表示,在传递参数之前要强制类型转换一下。

三、TCP通讯协议的基本流程

在实现TCP服务器之前,我们必须了解TCP通讯的基本过程,这样才能有一个比较清晰的思路实现我们的代码,基本流程图如下:
70
其基本过程如下: 服务器调⽤socket()、 bind()、 listen() 完成初始化后,调⽤accept()阻塞等待,处于监听端口的状态,客户端调⽤socket()初始化后,调⽤connect()发出SYN段并阻塞等待服务器应答,服务器应答⼀个SYN-ACK段,客户端收到后从connect()返回,同时应答⼀个ACK段,服务器收到后 从accept()返回。

四、服务器端与客户端通讯步骤

1、基于TCP的socket编程的服务器程序流程如下:

(1)创建套接字
(2)将套接字绑定到本地地址和端口上
(3)将创建的套接字设为监听模式,等待接收客户端的请求
(4)等待客户请求的到来,当请求到来后,接收连接请求,返回一个新的对于与此次连接的套接字
(5)用返回的套接字和客户端进行通信
(6).返回,等待另一个客户的请求
(7)关闭套接字

2、基于TCP的socket编程的客户度程序流程如下:

(1)创建套接字
(2)向服务器发出连接请求
(3)和服务器进行通信
(4)关闭套接字
客户端不需要绑定,如果绑定了,如果在同一台机器上启动多个客户端,就会出现端口号被占用导致不能正确连接。

五、客户端与服务器端程序(单进程)

1、客户端程序

2、服务器端程序

3、运行结果显示

要使程序成功通信,我们必须确保服务器端先运行,并且本机是开着的状态:
7

六、多进程服务器端版本

1、程序代码

2、优缺点

优点:
(1)可以处理多个进程
(2)代码易于编写
(3)多进程服务器稳定,因为进程运行具有独立性
缺点:
(1)服务器性能比较差:因为只有在有新的连接进入时,系统才创建进程。
(2)占用资源较多,同时服务的连接有上限,并且上限很容易达到。
(3)耗费成本大,进程创建的越多,导致进程切换的周期越长,成本也变大,进而也影响了服务器的性能。

承接各种网站开发与修改、爬虫、数据采集分析、小程序等任务

Html+Css+JS+PHP+Nodejs+Python

专治网站各种不服

一起探讨,互相学习,共同进步!有事儿您说话。

This entry was posted in C/C++ by 织梦先生. Bookmark the permalink.