计算机网络笔记--2 网络应用(下)

计算机网络笔记–2 网络应用(下)


前言

这是学习计算机网络课程时记录的笔记,里面大部分内容来源于哈尔滨工业大学李全龙老师的《计算机网络》mooc,加上我个人的理解整理出的内容。


2.6 P2P应用:原理与文件分发

C/S结构下:
服务器串行发送N个副本
时间:NF/Us
客户机i需要F/di时间下载
N很大时,总时间随N线性增长
在这里插入图片描述
在这里插入图片描述
P2P结构下
服务器至少发送一个副本:F/Us
客户机i需要F/di时间下载
总共需要下载NFbit
最快可能上传速率:Us+∑Ui
在这里插入图片描述
在这里插入图片描述
直观对比
在这里插入图片描述
P2P结构应用样例:BitTorrent
在这里插入图片描述
文件分为256KB的chunk
节点加入torrent
没有chunk,但是会逐渐积累
向tracker注册并获得节点清单,与某些节点连接
下载的同时,节点需要向别的节点上传chunk(互相共享)
一旦节点获取了文件,可能(自私的)离开或者(无私的)留下
获取chunk:
任意时刻,不同节点持有文件不同的chunk集合
节点定期查询每个邻居所持有的chunk列表
节点发送请求,请求获取缺失的chunk
稀缺优先(100节点有Achunk,3节点有Bchunk,优先获取Bchunk)——>让稀缺数据块尽量分布均衡
发送chunk:tit-for-tat
Alice向四个邻居发送chunk(选自:正在向Alice发送chunk速率最快的四个,每10秒进行一次评估) ——————>上传速率更高,更能找到好的合作伙伴
每30秒随机选择一个其他节点向其发送chunk——>为了预防局部化现象
新选择节点可能加入Top-4
“optimistically unchoke”
BitTorrent对网络有潜在危害

P2P应用的:索引技术
索引:信息到节点位置(IP地址+端口号)的映射
文件共享(电驴)
利用索引动态跟踪节点所共享文件的位置
节点需要告诉索引他有哪些文件
节点搜索索引,去了解能得到有哪些文件

即时消息(QQ)
索引负责将用户名映射到位置
当用户开启IM应用时,需要通知索引他们的位置
节点检索索引,确定用户IP地址

一:集中式索引(只提供索引服务不提供内容服务)
Napster最早采用
1.节点加入时,通知中央服务器他的:IP地址和内容
2.Alice查找文件
3.Alice从Bob处请求文件(P2P过程)

缺点:
内容和文件的传输是分布式的
但是内容的定位是高度集中的——>一个中央服务器储 存地址
单点失效问题
性能瓶颈
版权问题
一:集中式索引(只提供索引服务不提供内容服务)
Napster最早采用
1.节点加入时,通知中央服务器他的:IP地址和内容
2.Alice查找文件
3.Alice从Bob处请求文件(P2P过程)

缺点:
内容和文件的传输是分布式的
但是内容的定位是高度集中的——>一个中央服务器储 存地址
单点失效问题
性能瓶颈
版权问题
在这里插入图片描述
二:洪泛式查询(Query Flooding)
完全分布式架构
Gnutella采用这种架构
每个文件只对他共享的文件进行索引
覆盖网络:节点X和Y之间有TCP连接——>构成一条边
所有活动节点和边构成覆盖网络(overlay network叠在Internet之上,社交网络同理)
边:虚拟链路
节点一般邻居数少于10个
1.查询消息通过已有的TCP连接发送
2.节点转发查询消息
3.如果查询命中,则利用反向路径返回查询节点

缺点:
洪泛式查询会大量消耗网络带宽,导致网络拥塞。
网络形成的时侯比较复杂
在这里插入图片描述
三:层次式覆盖网络
介于集中式查询和洪泛查询之间的方法
每个节点如果不是超级节点,就会被分配一个超级节点
节点和超级节点间维持TCP连接
某些超级节点对之间维持TCP连接
超级节点负责跟踪子节点内容
在这里插入图片描述
Skype成功应用层次式覆盖网络
本质上P2P:用户/节点对直接通信
私有应用层协议
采用层次式网络覆盖结构
索引负责维护用户和IP地址间的映射
索引分布在超级节点上
在这里插入图片描述

2.7 Socket(套接字)编程-应用编程接口(API)

在这里插入图片描述
API:应用进程的控制权和操作系统的控制权进行转换的一个系统调用接口在这里插入图片描述
几种典型的应用编程接口
Berkeley UNIX操作系统 ——>套接字接口——>简称套接字(Socket)
微软——>Windows Socket Interface,WINSOCK
AT&T为其UNIX系统定义了一种API,简写为TLI(Transport Layer Interface)

Socket编程——Socket API概述
最初设计:面向BSD UNIX-Berkeley,面向TCP/IP协议栈接口
目前:事实上的工业标准,绝大多数操作系统都支持
Internet网络应用最典型的API接口
通信模型:客户/服务器(C/S)
应用进程间抽象的通信机制在这里插入图片描述
标识通信端点(对外):IP地址+端口号
操作系统/进程管理套接字(对内):套接字描述符——>小整数在这里插入图片描述
Socket抽象
类似于文件的抽象
当应用进程创建套接字时,操作系统分配一个数据结构存储该套接字相关信息
返回套接字描述符在这里插入图片描述
地址结构
使用TCP/IP协议簇的网络应用程序声明端点地址变量是,使用结构sockaddr_in
在这里插入图片描述
API函数
1.WSAStartup(在windows系统下必须事先调用,其他操作系统已经自动实现了)
Int WSAStartup(WORD wVersionRequested,
LPWSDATA lpWSAData)
使用Socket的应用程序在使用Socket之前必须首先调用WSAStartup
两个参数:
第一个参数指明程序请求使用的WinSock版本,其中高位字节指明副版本、低位字节指明主版本:十六进制整数,例如0x102表示2.1版
第二个参数返回实际的WinSock的版本信息:只想WSADATA结构
例:使用2.1版本的WinSock的程序代码段
wVersionRequested= MAKEWORD(2,1);
err=WSAStartup(wVersionRequested,&wsaData)在这里插入图片描述
2.WSACleanup
Int WSAClenaup(void)
应用程序在完成对请求的Socket的时候后,最会要调用WSACleanup函数
解除和Socket库的绑定
释放Socket所占用的系统资源

3.Socket函数在这里插入图片描述
创建套接字
操作系统返回套接字描述符(sd)
第一个参数(协议族):protofamily=PF_INET(TCP/IP下的类型)
第二个参数:套接字类型
第三个参数(协议号):0为默认

在这里插入图片描述
三种类型的套接字在这里插入图片描述
SOCK_RAW:原始套接字(课程不细讲)
SOCK_STREAM:可靠、面向连接、字节流传输、点对点、全双工
SOCK_DGRAM:不可靠、无连接、数据报传输

4.Closesocket
在这里插入图片描述
关闭一个描述符为sd的套接字
如果多个进程都是用同一个套接字,调用closesocket将引用计数减一,直到为0关闭
一个进程的多线程对一个套接字的使用无引用计数——>有一个线程关闭套接字则其他线程都不能用了
返回值:0——>成功,SOCKET_ERROR——>失败

5.Bind在这里插入图片描述
绑定套接字的本地端点地址
IP地址+端口号
参数:
套接字描述符:sd
端点地址:localaddr---->结构sockaddr_in
客户程序一般不必调用bind函数,因为操作系统一般就解决了
但是服务器端需要调用:这样客户端就可以根据bind找到服务器在这里插入图片描述
上图的解决方案
地址通配符:INADDR_ANY——>任何一个套接字进来的客户端都可以访问这个服务器
把sd设置为INADDR_ANY这样所有API均可访问

6.Listen在这里插入图片描述置服务器端的流套接字处于监听状态
仅服务器端调用
仅用于面向连接的流套接字
设置连接请求队列的大小(queuesize)

返回值:
0:成功
SOCKET_ERROR:失败

7.Connect在这里插入图片描述
只用于客户端
客户程序调用connect函数来使客户套接字(sd)与特定计算机的特定端口(saddr)的套接字(服务)进行连接
可用于TCP和UDP客户端
TCP客户端:建立TCP连接
UDP客户端:指定服务器端点地址(但是并未建立连接)在这里插入图片描述
8.accept在这里插入图片描述
服务程序调用accept函数从处于监听状态的流套接字sd的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与其创建连接通道
——>仅用于TCP套接字,仅用于服务器
结果:利用新创建的套接字与(最前面的)客户通信
如果没有accept,那么服务器在任何时刻
在这里插入图片描述

9.send sendto在这里插入图片描述
Send函数用于TCP套接字(客户端与服务器)或调用了connect函数的UDP客户端套接字
Sendto函数用于UDP服务器端套接字与未调用connect函数的UDP客户端套接字

10.recv,recvfrom
recv函数从TCP链接的另一端接收数据,或者从调用了connect函数的UDP客户端套接字接收服务器发来的数据
recvfrom函数用于从UDP服务器端套接字与尾调用connect函数的UDP客户端套接字接受对端数据在这里插入图片描述
11.setsockopt,getsockopt在这里插入图片描述
Setsockopt()函数用来设置套接字sd的选项函数
Getsockopt()函数用于获取任意类型、任意状态套接口的选项当前值,并把结果存入optval

函数小结在这里插入图片描述
网络字节顺序
TCP/IP定义了标准的用于协议头中的二进制整数表示:网络字节顺序
也就是说,很多Socket API函数的参数需要存储为网路字节顺序(如IP地址、端口号)
所以要有可以实现本地字节顺序与网络字节顺序间转换的函数:
htons 本地——>网络16bits
ntohs 网络——>本地 16bits
htohs 本地——>网络 32bits
ntohl 网络——>本地 32bits在这里插入图片描述
Socket编程-客户端软件设计
客户端可能使用域名(study.163.com)或IP地址(如:123.58.180.121)标识服务器
IP协议需要使用32位二进制IP地址
需要将域名或者IP地址转换为32位IP地址
12.函数inet_addr()实现点分十进制IP地址到32位地址的转换
13.函数getthostbyname()实现域名到32位IP地址转换——>返回一个指向结构hostent的指针在这里插入图片描述
解析服务器(熟知)端口号
客户端还可能使用服务名(如HTTP)标识服务器端口
14.需要将服务名转换为熟知端口号——>getservbyname()返回一个指向结构servent的指针在这里插入图片描述
解析协议号
客户可能使用协议名(如TCP)指定协议

15.需要将协议名解析为协议号—>getprotobyname()实现转换,返回一个指向protonent的指针在这里插入图片描述TCP客户端软件流程
1.确定服务器IP地址及端口号
2.创建(客户端的)套接字
3.分配本地端点地址(IP地址+端口号)——>不需人为,操作系统自动解决
4.连接远程服务器(connect函数——>套接字)
5.遵循应用层协议进行通信(例如谁先发网路信息等)
6.关闭/释放连接

UDP客户端软件流程
1.确定服务器IP地址及端口号
2.创建(客户端的)套接字
3.分配本地端点地址(IP地址+端口号)——>不需人为,操作系统自动解决
4.指定服务器端点地址,构造UDP数据报
5.遵循应用层协议进行通信 UDP服务器永远不知道有客户需要访问他
6.关闭/释放套接字
客户端软件的实现(某一种思路)-connectsock()
四种类型基本服务器
一:循环无连接服务器
二:循环面向连接的服务器
三:并发无连接的服务器
四:并发面向连接的服务器

一:循环无连接服务器
1.创建套接字
2.绑定端点地址(INADDR_ANY+端口号)
3.反复接受来自客户端的请求
4.遵循应用层协议,构造响应报文,发送给客户
数据发送:
服务器端不能使用connect()函数,因为是无连接的
无连接服务器使用sendto()函数发送数据报
在这里插入图片描述
获取客户端点地址:
调用recvfrom()函数接收数据时,自动提取在这里插入图片描述
二:循环面向连接的服务器
1.创建(主)套接字,并绑定熟知端口号
2.设置(主)套接字为被动监听模式,准备用于服务器
3.调用accept()函数接受下一个连接请求(通过主套接字),创建新套接字用于与该客户建立连接
4.遵循应用层协议,反复接受客户请求,构造并发送响应(通过新套接字);
5.完成为特定客户服务后,关闭与该客户之间的连接,返回步骤3
三:并发无连接的服务器
在这里插入图片描述
四:并发面向连接的服务器(因为是点对点连接,所以每个用户都有一个单独的套接字)
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值