计算机网络笔记:第三章--客户服务器交互

引子:

协议软件并不会主动去初始化或接受来自远程电脑的连接。在任何通信过程中,都需要两个应用进程。一个用于建立连接,另一个接收连接。
而应用进程会告知本地协议软件:只有特定类型的信息才允许接收,然后进程就会进入等待状态。当到来的信息匹配上了进程要求的那种类型,协议软件就会把信息传给应用进程。
总之:一个进程主动连接,另一个被动等待信息。

C/S模式

客户端:主动建立连接(initiate)的那一端(可以多个)
服务器端:被动等待(wait)连接的那一端(一对多)

客户端:一个在本地PC上运行的,向服务端发出请求的程序

特点:

  • 有限工作
  • 主动建立/断开连接
  • 在用户的PC本地运行
  • 一次只可以和一个远端服务器连接,但如果需要的话,可以同时使用多个服务(来自同一个server)
    它是有限工作的,即 当有限次的主动请求的服务被响应完后,就可以主动结束连接。
服务端:一个运行在远端机器上为客户端提供服务的程序

特点:

  • 被动打开,可以被任意的远程客户端访问
  • 自动被调用,无限运行的程序(除非被强制关闭)
  • 需要强大的硬件支持

传输协议和服务器与客户端的交互

客户端和服务器使用传输层的协议来通信。所以需要二者具有完整的协议栈。
注意网络层的IP协议只支持到主机层面,而传输层深入到了主机的哪个进程(port区分)在通信。
所以可以看到UDP(高效率但不可靠信道)和TCP(全双工可靠信道)协议包中都有端口号这一项。

传输协议会分派给各个服务一个标识id。client和server都会通过id来识别是哪种服务。
传输协议也会给每个客户端,服务端一个id。
tcp:源主机+端口。目的主机+端口。得知是哪两个进程之间的通信。
udp:同理。

client和server各个端口都有一个 outgoing queue和incoming queue用于存放各请求和响应。
一台主机上的不同进程复用tcp/udp(仅仅是端口号不同)都打包成tcp/udp包然后复用ip(都打包成ip包)发送到另一台主机,ip分用后再tcp和udp分用到各个端口。

插口:IP+PORT

标识进程。
UDP使用socket来区分多个主机同时通信的多个进程。

端口的分类

熟知端口:0~1023

  • 0~255 公共应用层协议(类似119,120,大家都知道) 像FTP(20,21) http(80)

  •    7 echo
    
  •   20 21 ftp (data control)
    
  •   53 dns
    
  •   80 http
    
  • 256~1023 OS开发公司为市场化的应用层协议编号
    一般端口:1024~65535 (普通应用程序)

  • 1024~49151 注册使用

  • 49152~65535 OS随机分配

并发:借助单个服务的服务器多拷贝(子进程)

服务器端可以有一些子进程分担主进程的请求。
一个电脑允许多个应用程序同时允许来支持并发。
一个程序有多个线程控制就是并发程序。
C/S模型交互最基本的模型就是并发模型。
client和server都可以是并发模式。
服务端的并发:

  • 迭代无连接的服务(udp)
  • 面向连接的并发服务(tcp)
    对于服务器端的缓冲区队列是有限的。
    如果同一时间上千万台Client同时请求,缓冲区溢出,服务器就会崩溃。
    UDP和应用层的端口都是用报文队列来实现。
    OS为该进程(端口)创建一个入队列(incoming queue)和出队列(outgoing queue)。

并发过程

  1. 客户端请求连接
  2. 服务端接收连接,产生一个子进程,子进程拷贝主进程的源代码,建立起和主进程的client连接
  3. 主进程关闭和client的连接,等待和其他client的连接,重复2步骤。

永远尽量保持住进层空闲,这样可以用子进程实现并发,同时处理多个client的请求。

三层模型

DB和server也分离,如果client请求数据,server需要向DB请求。

n层模型

多个server,并发能力很强。
每次分层都相当于是对请求数量的一次缓冲。

P2P模式(拓展)

角色对等模式。CS是一主一从,P2P是peer to peer,二者地位一致。
譬如p2p下载就是只要可连接且有资源的那些主机都可以同时为我的电脑下载然后传过来,这样就非常快。(索引机制)

socket接口

应用程序和协议软件交互使用的接口就是API。它定义了一个操作集合(函数集合)用于和协议软件交互。

socket API

对各个OS都可用。源于BSD Unix。我们可以基于socket API编程。
unix系统的命令集,模式是打开-读写-关闭。
一个用户进程进行IO操作时,调用“打开”获得对指定文件或者设备的使用权。多次调用,读写。操作完成,关闭调用。

socket descriptor network I/O

socket

插口通信也使用描述符的方法。在进程使用协议通信之前,进程需要OS创建一个socket用于通信。系统返回一个小的整数描述符来代表这个创建好的socket。(类似FILE *fp = fopen(xxx); fp描述符就代表了这个文件)

bind

刚才申请的socket只有和应用程序绑定在一起(建立连接)后,传输层传给该端口的数据都会被理所当然的送到应用程序。
输出亦然。端口的IO操作可以类比文件。

通信进程的标识——协议端口,一个整数来表示不同端口
传输层和网络层在功能上最大的区别时传输层提供了进程之间的通信能力。
因此网络通信的最终地址不再仅仅是host地址,害包括描述进程的端口。(port)
另外TCP和UDP因为是完全独立的,所以二者的端口号也是相互独立的。
tcp的255和udp的255端口是不同的,二者不冲突。

半相关

三元组全局唯一标识一个进程
(协议,本地地址,本地port)
指定连接的一半部分

全相关

一个完整的网间通信需要两个进程组成,只能使用同一种高层协议。
一个完整的网间通信需要一个五元组来标识。
(协议,本地地址,本地port,远程地址,远程port)

socket接口

application的基本网络接口

  • OS提供
  • 进程的通信端点
  • socket的信息含义:全相关五元组

参数和插口API

插口编程不同于传统IO,插口更详细,所以参数更多。
插口结构见PPT 23/73
均是五元组。包含三个大参数:family,type,protocol

C/S执行模式

Server:

  • socket
  • bind 准备阶段结束
  • listen
  • accept 连接阶段结束
  • send/recv(loop here till end toward listen again) 通信阶段
  • close (compulsory) 关闭阶段

Client:

  • socket
  • connect 主动打开
  • send/recv
  • close
完成上述API的程序之 1.socket创建
descriptor = socket(protofamily , type,protocol)

成功返回一个int描述符
失败-1
为进程创一个socket。
protofamily:参数有:

  • AF-INET4 ipv4协议
  • AF-INET6 IPV6协议
  • AF-LOCAL unix域协议
  • AF-ROUTE 路由插口

type:三种类型插口

  1. SOCK_STREAM 字节流插口 (TCP) 像ftp
  2. SOCK_DGRAM数据报插口 (UDP)
  3. SOCK_RAW 原始插口 允许跳过传输层直接使用IP,ICMP(ping)等网络层协议服务

协议类型参数:
在头文件<netinet/in.h>
常量名以IPPROTO_开头
例如:

  • IPPROTO_ICMP
  • IPPROTO_IP

根据这三个参数可以看出来,创建出来的socket和进程屁关系没有,所以需要绑定。

2.绑定的过程:

调用格式:

bind(socket,localaddr,addrlen)

成功绑定返回0,否则-1;
bind是用于把进程和插口绑定起来,这样数据在socket中IO其实就是与进程IO。
socket是刚刚获得的descriptor
本地地址(ip)和地址长度(ip len)。
对服务器而言,绑定的端口一定得是一个已知的端口,不然客户端是无法得知向哪个端口建立connect,所以需要bind函数来手动设置参数
插口地址的结构以及通配地址(INADDR_ANY)详细见ppt 39/73.

socket_in地址的结构(三元组)

struct sockaddr_in{
	u_char sin_len;//server_in_len  地址总长
	u_char sin_family;//地址族
	u_short sin_port;  //协议端口号
	struct in_addr sin_addr;//IP
	char sin_zero[8];//保留位 0
};
struct in_addr{
	u_long s_addr;
}

将IP地址作为一个32位的二进制数来保存。

网络字节顺序

在网络协议中必须制定网络字节顺序。
TCP/IP协议使用16位整数和32位整数,大数在前格式。
主机既有大端也有小端。
总之都调用hton {s|l} 即可,自动调整。

host to network long/short
主机的数据要传到网络上去时候使用。
htons(l)(uint16(32)_t host_short(long));

network to host long/short
主机接收网络上的数据时使用。
ntohs(l)(uint16(32)_t network_short(long));

3.监听过程(server独有)

创建一个被动插口(socket),用本地插口地址域初始化(bind)。
这个函数告知OS服务器端已经准备用这个接口去接收连接。

listen(socket,queuesize)为socket创建缓冲队列的尺寸。
限制排队请求的个数,max目前是5
成功0,失败-1.

4.接收过程 accpet (server) 服务器端等待建立起连接

被tcp服务器端调用来移除第一个连接请求。当没有请求的时候,函数sleep。

newsock = accept(socket , caddress,caddresslen);//client address

socket(主进程):第一次服务器创建的那个绑定与指定协议端口的descriptor。
caddress是sockaddr类型
caddressken是一个指向整形的指针。accept是为该连接创一个新的socket(子进程)。并返回给调用者。这个插口才是真正用于通信的插口。用户服务完会关闭这个插口。(子进程)
服务器原始插口第一个socket是不变的。一直接受下一个用户的连接。(主进程)

5.连接过程(client)客户方建立连接

client主动连接到刚才accpet的新socket。

connect(socket,saddress,saddresslen);

成功0,失败-1.
socket是客户端上进程通信用的插口。saddress是服务器端的地址和协议端口号(IP+PORT)
saddresslen是字节形式的服务器地址长度

connect和accpet两个函数调用用于完成一个完整相关的建立。

6.正事:数据传输 send()和recv()

send(socket,data,lenth,flag);

/*socket 使用哪个插口
data 待发送数据在内存中的地址
length是数据字节数
flag是请求了特殊选项的位
*/
recv()调用于接收输入数据
recv( socket , buffer,length,flags);
buffer 存放数据的首地址

重复服务器一个时间只能和一个客户程序建立连接,他对多个客户请求的处理是采用循环进行的,所以叫重复服务器。
并发服务器可以改善响应速度,但是增加了 系统调度的开销。
重复服务器正好相反。

一些别的函数

memset
memcpy
memcmp
atoi 地址转换函数
Gethostbyname()网络信息查询函数

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值