网络编程
客户端-服务器编程模型
- 一个服务器进程对应一个或多个客户端进程
- 服务器管理资源
- 服务器操作资源来为客户端提供服务
- 服务器被客户端的请求激活
网络
- 分类
- SAN 系统区域网络
- 在机房间连接
- LAN 局域网
- WAN
- SAN 系统区域网络
- 互联网
- 广义的
- 互相连接的网络集合
- 狭义的
- 广义的
- 以太网段
- 主机
- hub
- 集线器
- 给每一个host都发送包(带地址),但只有一个是需要的
- 浪费 不安全
- 每一个以太网适配器都有一个独特的MAC地址
- MAC地址 计算机基本的标记
- 桥接以太网
- 网桥
- 会学习哪个主机可以通过哪个端口可达
- 选择性地将帧从一个端口复制到另一个端口
- 网桥
- 互联网络
- 多个不兼容的局域网通过路由器来凝结起来
网络协议
- 运行在每台主机和路由器上的协议软件实现协议
- 协议提供两种机制
- 命名机制
- 定义 host address 格式
- 每个主机和路由器都至少有一个独立的 internet 地址
- 传送机制
- 定义包
- 包头
- 包大小
- 主机地址
- 有效载荷
- 源主机发出的数据位
- 包头
- 定义包
- 命名机制
- PH:互联网包头
- FH:LAN帧头
全球IP因特网##
- 建立在TCP/IP协议家族上
- IP
- 基本的命名方式和传送机制,不会试图恢复网络中丢失或重复的数据包,不可靠
- UDP
- 稍微扩展了IP协议 使得包可以在进程间传送
- TCP
- 进程间双向的可靠的连接
- 保证能够收到
- IP
- 互联网结构
- 骨干网
- IXP 互联网交换节点
- 区域性网络
- 节点
- 网络服务提供商
- 因特网
- 一个世界范围的主机集合
- 主机被映射成一组32位的IP地址
- 这组IP地址被映射为一组称为因特网域名的标识符
- 不同主机之间的进程,可以通过 connection 来交换数据
- IP 地址
- 大端法
- 点分十进制表示法
- 每个字节(两个十六进制数)由它的十进制值表示
- 用.和其他字节分开
-
因特网域名
- 最后的是最大的 .com .cn
- DNS
- 定义了域名和IP地址的映射
-
因特网连接
-
客户端和服务器通过连接(connection)来发送字节流,特点是:
- 点对点: 连接一对进程
- 全双工: 数据同时可以在两个方向流动
- 可靠: 字节的发送的顺序和收到的一致
-
套接字是连接的一个断电
- 套接字地址
- IP地址+端口号
- 套接字地址
-
端口号
- 客户端端口是内核自动分配的临时端口
- 服务器端口通常是某个知名端口
- 80 Web
- 25 电子邮件
-
一个连接是由它两端的套接字地址唯一确定的
- 套接字对
-
- 客户端
- 不同的软件:浏览器、ssh
- 用IP+端口号寻找服务器
- 知名端口:7 echo server、80 web server
- 服务器
- 长期运行的进程
- 启动之后由init process创建
- 一直运行知道机器关闭
- 运行了一个服务进程的机器也被称为服务器
- Example
- Web server 80
- 来源:文件、compute cycles(CGI programs)
- retrives files 并基于客户端的行为运行CGI progrmas
- FTP server 20 21
- 接收文件
- 服务器存储并retrieve文件
- Telnet server 23
- 来源:终端
- 代理,服务器上的终端
- Web server 80
- 长期运行的进程
套接字接口
-
套接字
- 对于内核,套接字是一个连接的端点
- 对应用程序来说,套接字就是一个有相应描述符的打开文件
-
套接字地址结构
- sockaddr(_in)
- 包含用于网络连接的信息
- 协议信息+网络信息
-
相关函数
- socket函数
- 创建套接字描述符
- getaddrinfo函数可以自动生成参数
- connect函数
- connect函数会阻塞直到连接成功建立或错误
- bind函数
- 将addr中的服务器套接字地址和描述符联系起来
- listen函数
- 将sockfd从一个主动套接字转化为一个监听套接字
- 接受来自客户端的连接请求
- 将sockfd从一个主动套接字转化为一个监听套接字
- accept函数
- 等待来自客户端的连接请求到达监听描述符listenfd
- 在addr中填写客户端的套接字地址
- 返回一个已连接描述符
- socket函数
-
主机和服务的转换
- 二进制套接字地址结构和表示主机名、地址、服务名、端口号的字符串的转化
- getaddrinfo
- 线程安全的
- 协议无关的
- 复杂
- 将表示主机名、地址、服务名、端口号的字符串转化为套接字地址结构
- 给出hostname和servicename,函数返回result指向一个addrinfo结构的链表
- 客户端调用了函数后,遍历链表,直到socket和connect成功
- getnameinfo
- 和getaddrinfo相反
- getaddrinfo
- 二进制套接字地址结构和表示主机名、地址、服务名、端口号的字符串的转化
-
封装好的辅助函数
- open_clientfd
- open_listenfd
Web HTTP
-
Web基础
- Web客户端和服务器交互使用的是HTTP协议
- 客户端和服务器建立TCP连接
- HTTP请求 响应
- 关闭连接
- 现在的版本 HTTP/1.1
- Web客户端和服务器交互使用的是HTTP协议
-
Web内容
- 网页服务器返回内容给客户端
- 遵循MIME类型
- e.g.text/html、text/plain、image/gif…
- 遵循MIME类型
- 内容有静态的和动态的
- 静态内容
- 服务器里本来就有的
- 比如HTML文件、图片等
- 动态内容
- 服务器上本来没有,运行某些程序才能获得的资源
- 客户端提供一些参数
- 静态内容
- 基本规则:网页内容是和服务器上的一个文件相关的
- 网页服务器返回内容给客户端
-
URLs
- 网页是由包含若干个引用object的base HTML-file组成的
- 每一个object都和一个URL相关
- 静态内容的URLs
- 动态内容的URLs
-
- 如何使用URLs
- 客户端先使用前面的部分
- 协议
- 服务器位置
- 端口
- 服务器使用后面的部分
- 判断静态还是动态的内容
- 比较复杂的过程
- eg:cgi-bin
- 在文件系统中寻找文件
- 若只给了目录的位置则访问默认的文件
- 判断静态还是动态的内容
-
HTTP
- 超文本传输协议
- 网页应用级别的协议
- 客户端/服务器模式
- HTTP请求
- 请求行,跟着0或更多个报头
- 请求行:< method >< uri >< version >
- method是操作的种类 GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE
- uri是URL的一部分或者完整的
- URL是一种URI
- version是请求的HTTP版本
- 报头
- 向服务器提供额外的信息
- 请求行:< method >< uri >< version >
- 请求行,跟着0或更多个报头
- HTTP响应
- 响应行,跟着0或更多个报头,可能还跟着内容,用空白行分割(“\r\n”)
- 响应行:< version >< status code >< status msg >
- 版本
- 数字状态
- 响应的英文文本
- 200 OK
- 301 MOVED
- 404 Not found
- 响应行:< version >< status code >< status msg >
- 响应报头< head name >:< head data >
- 提供附加的信息
- 内容类型 返回内容的MIME类型
- 内容长度
- 响应行,跟着0或更多个报头,可能还跟着内容,用空白行分割(“\r\n”)
- HTTP版本
- HTTP/1.1 HTTP/1.0
例子
- 代理
- 在客户端和原始服务器之间的媒介
- 在请求和响应时可以运行一些有用的函数
- 更快、便宜
- 显式的代理
- 在浏览器上设置的,浏览器知道的
- 每一条请求指定整个URL
- 透明的代理
- 浏览器/客户端看不到