∣ 应 用 层 ∣ ⏡ ⏠ ∣ 运 输 层 ∣ ∣ 网 络 层 ∣ ∣ 链 路 层 ∣ ∣ 物 理 层 ∣ \Huge \overgroup{\undergroup{| 应用层|}}\\ | 运输层 |\\ | 网络层 |\\ | 链路层 |\\ | 物理层 |\\ ∣应用层∣ ∣运输层∣∣网络层∣∣链路层∣∣物理层∣
这一篇分为四个部分
- 应用层概念解释:了解应用层的一些概念
- 与运输层衔接的内容:了解与应用层内容有重叠的运输层的一些概念
- 常见网络应用与应用层协议:详细考察Web、电子邮件、DNS、对等文件分发、视频流等网络应用程序
- 简单网络应用开发:使用Python写简单的客户-服务器应用程序
-应用层概念-
客户与服务器
客户-服务器体系结构
(Client-Server Architecture)
一个总是打开的主机作为服务器,用于服务其他客户主机的请求
客户之间不直接通信
服务器具有固定、周知的IP地址。
该结构的应用程序有Web、FTP、Telnet、电子邮件…
数据中心配备大量的主机,用于处理大型的网站的大量客户的请求
谷歌再全世界分布有30~50个数据中心来维持服务
服务供应商必须支付高昂的电费、维护费、带宽费
P2P体系结构
(Peer to Peer Architecture)
对专用服务器几乎没有依赖
主机之间直接通信,相互通信的主机对被称为对等方
该结构的应用程序有BitTorrent、迅雷、Skype…
P2P具有自扩展性,每个对等方由于请求文件产生负荷,但每个对等方同时通过向其他对等方分发文件来增加服务能力
P2P对公共网络的安全与性能有一定影响
混合体系结构
同时应用C/S与P2P
如许多即时讯息应用,服务器用于跟踪用户IP,而用户报文则直接在对等方间传输。
进程
进程是运行在端系统上的一个程序。
在不同端系统上,进程通过发送与接收报文(message)来相互通信
(在同一端系统中的进程间通信由操作系统控制,但本书不关注)
客户服务器进程
客户进程:发起通信的进程
服务器进程:接收信息的进程
如:
在C/S结构的Web应用中,浏览器为客户,Web服务为i为服务器。
在P2P结构的文件共享应用中,下载文件的对等方为客户,上载文件的对等方为服务器,而P2P中有时一个进程既是客户又是进程。
进程寻址
客户端进程会拥有一个由主机IP地址(32b大小,可唯一标识主机)与端口号(一台主机会同时运行多个应用,于是主机有许多端口,每个端口独立接收信息,不同的进程不能使用同一个端口)组成的标识。
客户进程在发送报文时使用标识,使得报文能正确到达服务器进程
如:
Web服务器使用端口号80
邮件服务进程使用端口号25
运输层接口-套接字
套接字(socket)是应用程序编程接口用于帮助应用层网络应用向网络发送、接收报文。
套接字是应用层与运输层的接口,在两层各有渗透
应用程序开发者可以控制套接字在应用层的部分,而无法控制运输层部分(仅能选择运输层协议、若干个参数,如最大缓存、最大报文长度)
与运输层衔接的内容
协议功能
由于需要通过套接字来指定运输层使用的协议,因此需要了解协议一般有哪几类功能
可靠数据传输服务
某些运输层协议可以确保客户进程发出的数据正确、完全地交付到服务器进程
并不是所有应用都必须要数据完全正确且不丢失
容忍丢失应用(loss-tolerant application)能够承受一定量的数据丢失,比如一些多媒体应用(交谈式音频/视频)
稳定吞吐量服务------------------------------存疑,吞吐量和定时子啊因特网电话中的体现是?
某些运输层协议可以使得应用能够请求稳定的吞吐量
吞吐率是客户进程向服务器进程交付比特的速率
由于网络路径是共享的,随时会有不同的运输任务开始或完成,吞吐率会随时间变化
带宽敏感应用(bandwidth-sensistive application)对交付时间比较敏感的应用,必须要求吞吐率保持某一速率或在该速率以上。如网络电话一类的多媒体应用,接收所需吞吐量的一半是几乎没有用的。
弹性应用 (elastic application)对交付时间没有要求的应用,有多少就用多少吞吐量。如电子邮件、文件传输、Web传送。
定时保证服务------------------------------存疑
某些运输层协议提供定时保证,如客户进程注入套接字中的每个比特到达接收方的套接字不迟于100ms
适用于交互式实时应用,为了有效性而又严格的时间限制。如因特网电话、虚拟环境、电话会议、多方游戏
安全性服务
某些运输层协议提供若干种安全性服务,加密、解密报文,完整性和端点鉴别
运输层协议
TCP运输服务协议
TCP服务模型包括面向连接服务、可靠数据传输服务
- 面向连接服务:在发送真正的应用层报文之前,客户和服务器交换运输层控制信息,经历三次信息交换(或称”握手“)后,就建立了一个TCP连接,发送完报文之后,必须拆除该连接
- 可靠数据传输服务:TCP能够无差错、安适当顺序交付发送的数据
TCP协议具有拥塞控制机制,对单个通信不能直接带来好处,但对整体因特网有益
UDP运输服务协议
UDP是不提供不必要服务的轻量级运输协议
UDP是无连接的,是一种不可靠数据传输服务
UDP没有拥塞控制机制,可以用其选定的任何速率向下(网络层)注入数据
补充
TCP与UDP都没有加密功能
安全套接字(Secure Socket Layer, SSL)为TCP的加强措施,使用SSL加强TCP后,能够提供加密、数据完整性、端点识别等安全性功能
虽然TCP和UDP都不提供吞吐量和定时保证,但是这类的应用被设计成尽最大可能应对这种保证缺陷,现在这类应用也运行的很好
因特网能为时间敏感应用提供满意度服务,但不提供保证
-网络应用与应用层协议-
在应用考察的过程中了解应用层协议
应用层协议描述进程如何构造报文
RFC文档定义了诸如HTTP(超文本传输协议)、SMTP(简单邮件传输协议)这样的公共域应用层协议
而还有一些专用应用层协议并不公开,如Skype的协议
Web与HTTP
Web的应用层协议是超文本传输协议(HyperText Transfer Protocol, HTTP)
关于HTTP
-
HTTP使用TCP作为其支撑运输协议
-
HTTP由一个客户程序(由Web浏览器实现)、一个服务器程序(由Web服务器实现)实现
客户向套接字发送HTTP请求报文,之后包问脱离用户控制,被TCP控制,TCP会将报文可靠的传输到服务器 -
HTTP是无状态协议(stateless protocol),服务器不维护(不保存)任何有关客户端过去所发请求的信息。
因此客户可以在几秒内反复请求同一个文件,服务器也会反复响应。 -
Web页面由对象组成,对象可以是HTML文件、图片、java小程序、视频等
一般Web页面通过HTML基本文件来组合其他的引用对象 -
URL(Uniform Resoure Locator):统一资源定位器
-
HTTP是一个拉协议(pull protocol),用户使用HTTP从服务器拉去数据
非持续连接/持续连接
往返时间(Round-Trip Time, RTT)一个短分组从客户到服务器,再返回客户所需的时间
-
非持续连接(non-persistent connection)是每次请求都重新建立一个TCP连接,一下过程与上图2-7一样
1. 客户向服务器发送小TCP连接请求报文 使用0.5RTT
2. 服务器向客户发送小TCP确认响应报文 使用0.5RTT
3. 客户向服务器发送确认TCP确认报文以及HTML请求报文 使用0.5RTT
4. 服务器传输HTML文件 第一个比特到达的时间是0.5RTT
那么非持续的响应时间是2*RTT+传输HTML文件的时间 -
持续连接 (persistent connection)是一段时间内的请求都在同一个TCP连接中进行,流水传输报文。理想状态,收到所有的引用对象只需耗时1个RTT。HTTP1.1之后,默认使用持续连接。
浏览器可同时打开多个连接:
- 并行的TCP连接:并行数大于1。默认打开5~10个。
- 串行的TCP连接:最大并行数为1。
Web缓存
Web缓存(或称代理服务器)既充当客户端,也充当服务器,能够在不访问服务器的前提下满足客户端的HTTP请求,用以
- 缩短客户请求的响应时间
- 减少机构/组织的流量
- 在大范围内(Internet)实现有效的内容分发
报文格式
报文使用ASCII文本书写
请求报文
GET /somedir/page.html HTTP/1.1
Host: www.someschool.edu
Connectionn: close
User-agent: Mozilla/5.0
Accept-language: fr
# 下面是解释
# 第一行为请求行
# 方法字段“GET”、URL字段“/somedir/page.html”、HTTP版本字段“HTTP/1.1”
# 方法有GET、POST、HEAD、PUT、DELETE
GET /somedir/page.html HTTP/1.1
# 之后的都叫首部行
# Host首部行:指明对象所在主机
Host: www.someschool.edu
# Connection首部行:是否使用持续连接,close是不使用
Connectionn: close
# User-agent首部行:指明用户代理(浏览器类型)
User-agent: Mozilla/5.0
# Accept-language首部行:指明需要对象的哪种语言版本,
Accept-language: fr
方法字段值
方法 | 用法 |
---|---|
GET | 请求URL对象 |
POST | 在需要用户提交表单时和实体体一起使用 |
HEAD | 用于开发者调试跟踪,该请求的响应只返回一个HTTP报文 |
PUT | 允许用户上传对象到指定Web服务器 |
DELETE | 允许用户删除Web服务器上的对象 |
实体体在需要用户提交表单时使用,如使用POST方法,来向服务器提供账号密码,或向搜索引擎提供搜索关键词
但是GET方法同样可以提供表单,它将表单内容存放于URL中
如
www.somesite.com/animalsearch? monkey&bananas
传输了monkey和banan两个数据
条件GET
条件GET用于验证缓存中的对象是否为最新版本,如果缓存有最新的版本,则响应消息中不包含对象(HTTP/1.0 304 Not Modified)
条件GET的组成:
- 请求报文使用GET方法
- 请求报文中含有If-Modified-Since首部行
响应报文
HTTP/1.1 200 OK
Connection: close
Data: Tue, 18 Aug 2015 15:44:04 GMT
Server: Apache/2.23 (CentOS)
Last-Modified: Tue, 18 Aug 2015 15:11:03 GMT
Content-Length:6821
Content-Type: text/html
(data ........)
# 解释
# 初始状态行
# 协议版本字段、状态码、状态信息
HTTP/1.1 200 OK
#之后都是首部行
# Connection首部行:发送完报文后是否关闭连接,close是关闭
Connection: close
# Data首部行:服务器发送响应报文的时间(非对象创建、修改日期)
Data: Tue, 18 Aug 2015 15:44:04 GMT
# Server首部行:服务器类型
Server: Apache/2.23 (CentOS)
# Last-Modified首部行:对象创建、修改的日期
Last-Modified: Tue, 18 Aug 2015 15:11:03 GMT
# Content-Length首部行:发送中对象的字节数
Content-Length:6821
# Content-Type首部行:实体体中对象的类型,这里是HTML文本类型
Content-Type: text/html
# 实体体
(data ........)
常见状态码
状态码 | 状态短语 | 解释 |
---|---|---|
200 | OK | 请求成功 |
301 | Moved Permanently | 请求对象永久转移,新的URL在响应报文Location首部行中 |
400 | Bad Request | 该请求不能被服务器理解 |
404 | Not Found | 被请求文档不在服务器 |
505 | HTTP Version Not Supported | 服务器不支持请求报文使用的HTTP协议版本 |
用telnet看真实的HTTP报文(失败了)
由于win10 默认关闭telnet客户端功能,先打开telnet功能
开一个终端,输入(很容易遗失对主机的连接,换了好几个一个国内的网址也不行,失败了)
telnet gaia.cs.umass.edu 80
正在连接的提示一闪而过
然后是一个空白页
按Ctrl+]
再回车,回到空白页
输入下面内容,输入完按两次回车
GET /kurose_rose/interactive/index.php HTTP/1.1
Host: gaia.cs.umass.edu
cookie
无状态的HTTP服务简化了服务器设计,然而Web站点的某些功能需要识别用户身份,如购物车的实现
cookie使得站点能够跟踪用户
cookie有四个组件
- HTTP响应报文中的cookie首部行
- HTTP请求报文中的cookie首部行
- 由浏览器管理的,保存在用户端系统中的cookie文件
- Web站点的后端数据库
cookie可能会对用户隐私造成侵害
电子邮件
电子邮件组成
- 用户代理(user agent)
- 允许用户阅读、回复、发送、保存、撰写报文
- 邮件服务器(mail server)
- 存储发送的Email到报文队列,报文队列通常每30分钟尝试发送邮件至对方的邮件服务器。
- 简单邮件传输协议(Simple Mail Transfer Protocol, SMTP)
- SMTP运行在邮件服务器上,既可以是客户端也可以是服务器端。
- SMTP运行在邮件服务器上,既可以是客户端也可以是服务器端。
简单邮件传输协议SMTP
- 限制邮件报文的体部分只能采用7比特ASCII码
- SMTP使用25端口
- 使用TCP可靠数据传输服务。
- 邮件不会停留在某个中间邮件服务器,只存在于发送方的邮件服务器或者接收方的 邮件服务器。
- SMTP是一个推协议 (push protocol)发送邮件服务器把文件推向接收邮件服务器 (与HTTP拉协议对比)
- SMTP的所有报文对象都在一个报文中(与HTTP引用对象对比)
SMTP客户(C )与SMTP服务器(S)交换报文三次握手的过程
邮件报文格式
alice@crepes.fr发送一个主题为Searching for the meaning of life.
的邮件给bob@hamburger.edu,邮件内容为balabala…
From: alice@crepes.fr
To: bob@hamburger.edu
Subject: Searching for the meaning of life.
balabala...
邮件访问协议
从图中可以看到,前两步都可以用推协议STMP实现,但是最后一步由于接收方的代理并非一直开启,如果还是使用STMP让接收方邮件服务器反复推邮件很不现实
因此第三步一般使用第三版邮局协议(Post Office Protocol-Version 3, POP3)、因特网邮件访问协议(Internet Mail Access Protocol, IMAP)、HTTP等拉协议
- POP3
- 无状态协议,端口110上使用TCP连接
- 用户读取邮件后,服务器不再保存
- IMAP
- 端口143上使用TCP连接
- 所有信息都保存在服务器,用户在代理操作服务器中的内容
- HTTP
- 端口80上使用TCP连接
- 用户在远程服务器上以层次目录方式组织报文
- 第一步、第三步使用HTTP,第二步邮件服务器之间使用SMTP
DNS:因特网的目录服务
用如www.facebook、www.google.com这样的主机名(hostname)来标识主机,然而主机名并不提供主机在因特网中的位置信息,于是也使用IP地址(IP address)标识
IP地址由4字节组成
DNS通常直接由其他的应用层协议 (包括HTTP、SMTP 和FTP)使用,以将用户提供的主机名解析为IP地址。用户只是间接使用。
域名系统(Domain Name System, DNS)提供一种将主机名转换到IP地址的目录服务,在端口53上使用UDP运输协议
- DNS是一个由分层的DNS服务器实现的分布式数据库
- DNS是一个使主机能够查询分布式数据库的应用层协议
DNS提供的服务
- 主机名到IP地址的转换
- 主机别名,一个有复杂主机名的主机可以有多个别名帮助记忆,而原来那个主机名称为规范主机名
- 邮件服务器别名,实际的邮件服务器地址并不想我们看到的好记,DNS将简单的邮件服务器地址关联到其规范主机名
- 负载分配,由于有些网站可能使用多个主机,DNS可以将一个主机名关联到一个IP地址合集
DNS工作机理概述
集中式DNS服务器(全网使用一台服务器,保存所有数据)的缺点
- 单点故障:如果该DNS服务器崩溃,则整个因特网瘫痪
- 通信容量:单个DNS服务器处理所有的查询,任务量太大
- 远距离的集中式数据库:单个DNS服务器不论部署在哪里都不可能兼顾到全球的用户,总有一部分的延迟非常高
- 维护:单个DNS服务器存储所有主机信息,数据库极大,难以维护
分布式、层次数据库
DNS服务器有三种类型
- 根DNS服务器:分布全世界,由13个组织管理,提供TLD服务器的IP地址
- 顶级域DNS服务器(Top-Level Domain, TLD):提供权威服务器的IP地址
- 权威DNS服务器:组织或公司维护的服务器
另外还有一类本地DNS服务器运行在用户本地作为代理
DNS服务器查询的迭代查询过程
主机cse.nyu.edu请求主机gaia.cs.umass.edu的IP地址
- 向本地服务器dns.nyu.edu发起查询
- 本地服务器向权威服务器发起查询
- 权威服务器读取到edu顶级域名,返回负责edu的顶级域服务器IP地址列表
- 本地向负责edu的顶级域服务器发起查询
- 顶级域服务器读取到umass.edu权威域名,返回权威服务器IP地址
- 本地向权威服务器发起查询
- 权威服务器读取gaia.cs.umass.edu,返回该主机的IP地址
DNS服务器查询的递归查询过程
DNS缓存
当本地DNS服务器得到一个回答时,它能能够缓存回答中的信息,一段时间内(一般为两天,之后会丢弃缓存信息),查询相同的主机名将不需要查询
DNS记录和报文
注册登记机构是验证域名唯一性,将域名输入DNS数据库的商业实体,可以通过它注册域名
资源记录(Resource Record, RR)提供了主机名到IP地址的映射,每条DNS回答报文包含若干条资源记录
资源记录为4元组,根据Type的值,来决定其他属性的具体含义
{Name, Value, Type, TTL}
- Type=A
- Name:主机名
- Value:该主机的IP地址
- Type=NS
- Name:域(foo.com)
- Value:知道该域IP的权威DNS服务器主机名
- Type=CHAME
- Name:规范主机名的别名
- Value:规范主机名
- Type=MX
- Name:邮件服务器别名
- Value:邮件服务器规范主机名
DNS报文
DNS的查询报文和回答报文格式相同
- 首部区域:包含几个字段
- 标识符:16b,标识该查询
- 标志:包含”查询/回答“、”权威“、”希望递归“、”递归可用“
- XX数:指出之后四个数据区域的数量
- 问题区域
- 名字:正在查询的主机名
- 类型:正在查询的问题类型(A、MX)
- 回答区域
- 包含回答的资源记录
- 权威区域
- 其他权威服务器的记录
- 附加区域
- 提供其他帮助记录,如MX请求回答报文包含了一条资源记录(其中是规范主机名),那么其附加区域可以是该主机名的别名
补充:DNS的脆弱性
分布式拒绝服务(DDoS)带宽泛洪攻击通过向DNS根服务器发送大量分组,使得其他合法的DNS请求得不到回答,使得网络瘫痪
对等文件分发
P2P文件分发特点
- 对等方间直接传输
- 可扩展性
- 对等方既可以使客户机、也可以是服务器
分发时间为所有N个对等方得到该文件副本所需的时间
F:分发的文件长度
u
s
u_s
us:服务器接入链路的上载速度
u
i
u_i
ui:第i个对等方接入链路的上载速度
d
i
d_i
di:第i个对等方接入链路的下载速度
d
m
i
n
d_{min}
dmin:N个对等方中最小的下载速度
D
c
/
s
D_{c/s}
Dc/s:C/S结构的分发时间
D
p
2
p
D_{p2p}
Dp2p:P2P结构的分发时间
C/S体系分发时间
服务器向N个对等方上载一个副本,需要时间为
N
F
u
s
\frac{NF}{u_s}
usNF
N个对等方下载完需要时间至少为
F
d
m
i
n
\frac{F}{d_{min}}
dminF
那么
D
c
/
s
≥
m
a
x
{
N
F
u
s
,
F
d
m
i
n
}
D_{c/s} \geq max\{\frac{NF}{u_s}, \frac{F}{d_{min}}\}
Dc/s≥max{usNF,dminF}
P2P体系分发时间
服务器必须接入网络至少上载一次文件,需要时间
F
u
s
\frac{F}{u_s}
usF
N个对等方下载完需要时间至少为
F
d
m
i
n
\frac{F}{d_{min}}
dminF
每个对等方可以作为服务器来上载,系统的总上传能力为
u
s
+
∑
i
=
1
N
u
i
u_s + \sum^N_{i=1}u_i
us+∑i=1Nui
系统必须上传N个文件,因此全部上传的时间为
N
F
u
s
+
∑
i
=
1
N
u
i
\frac{NF}{u_s + \sum^N_{i=1}u_i}
us+∑i=1NuiNF
那么
D
p
2
p
≥
m
a
x
{
F
u
s
,
F
d
m
i
n
,
N
F
u
s
+
∑
i
=
1
N
u
i
}
D_{p2p} \geq max\{\frac{F}{u_s}, \frac{F}{d_{min}}, \frac{NF}{u_s + \sum^N_{i=1}u_i}\}
Dp2p≥max{usF,dminF,us+∑i=1NuiNF}
可见P2P的分发时间总是小于C/S
BitTorrent
BitTorrent是一种用于文件分发的流行P2P协议
洪流(torrent)是参与一个特定文件分发的所有对等方的集合
在一个洪流中的对等方彼此下载等长度的文件块(chunk)
每个洪流具有一个基础设施节点叫追踪器(tracker),用于记录加入洪流的对等方
获取块
- 给定任一时刻,不同的节点持有文件的不同块集合
- 节点定期查询每个邻居所持有的块列表
- 最稀缺优先:用户最先请求在它邻居中副本数量最少的块
一报还一报(tit-for-tit)
- 疏通:用户每10s持续测量向它发送比特的邻居的速率,选择其中最快的4个,向他们发送块
- 每30秒随机选择一个其他节点,向其发送块
视频流
视频是由恒定速率播放的图片组成的
速率越快,图片质量越高,视频表现越好
HTTP流和DASH
在HTTP流中,视频存储在HTTP服务器中,么个视频又有一个url,客户与服务器建立TCP连接并请求其url得到该视频
这种方式每个用户得到相同编码的视频,无法兼顾不同带宽的用户
经HTTP的动态适应性流(Dynamic Adaptive Streaming over HTTP, DASH)将视频编码为不同的版本,每个版本不同比特率,客户动态请求不同版本的长度为几秒的视频段数据块,这样就可以根据带宽不同,动态调节视频比率
使用DASH使,不同版本的视频由不同的url
HTTP的告示文件为每个版本提供一个URL和比特率
内容分发网(Content Distribution Network, CDN)管理分布在 多个地理位置的服务器(其中层出视频文件的副本),试图将每个用户请求定位到提供最好体验的CDN位置
CDN可以是由内容提供方拥有的专用CDN,也可以是第三方CDN
- 深入:连接ISP的服务器集群来减少端用户和CDN集群的链路和路由器数量,高度分布式。
- 邀请做客:在关键位置建造大集群来邀请到ISP做客,维护、管理开销较低
-简单网络应用开发-
因为书上是用python2写的,代码略有改动
没有两个主机,服务器地址都填的本机名,自己发自己了
UDP套接字编程
"""
python3
UDPClient.py
"""
from socket import *
serverName = 'localhost' # 服务器的主机名/IP地址
serverPort = 12000 # 服务器端口号
# 创建客户套接字
clientSocket = socket(AF_INET, SOCK_DGRAM) # (地址簇=底层使用IPv4, 套接字类型=UDP套接字)
# 读取输入
message = input('Input lowercase sentence:')
# 字符串报文转化为字节 设置目的地址 向进程套接字发送分组
clientSocket.sendto(message.encode(), (serverName, serverPort)) # (字节型报文, (服务器主机名/IP, 服务器端口号))
# 等待得到收到信息(分组数据, 源地址)
modifiedMessage, sercerAddress = clientSocket.recvfrom(2048) # 取缓存长度2048作为输入
print(modifiedMessage.decode())
# 关闭套接字、进程
clientSocket.close()
"""
python3
UDPServer.py
"""
from socket import *
serverPort = 12000 # 服务器端口号
# 创建服务器套接字
serverSocket = socket(AF_INET, SOCK_DGRAM) # (地址簇=底层使用IPv4, 套接字类型=UDP套接字)
# 绑定端口号与服务器套接字
serverSocket.bind(('', serverPort))
print('The server is ready to receive')
while True:
# 等待得到收到信息(分组数据, 源地址)
message, clientAddress = serverSocket.recvfrom(2048) # 取缓存长度2048作为输入
message = message.decode()
print("Have receiveed message:", message)
modifiedMessage = message.upper()
# 发送报文
serverSocket.sendto(modifiedMessage.encode(), clientAddress) # (传输的报文, 客户地址)
分别运行两端代码
在客户端这边输入一些小写字母,回车
结果
TCP套接字编程
"""
python3
TCPClient.py
"""
from socket import *
serverName = 'localhost' # 服务器的主机名/IP地址
serverPort = 12000 # 服务器端口号
# 创建客户套接字
clientSocket = socket(AF_INET, SOCK_STREAM) # (地址簇=底层使用IPv4, 套接字类型=TCP套接字)
# 建立TCP连接
clientSocket.connect((serverName, serverPort))
# 读取输入
sentence = input('Input lowcase sentence:')
# 字符串报文转化为字节 发送分组
clientSocket.send(sentence.encode())
# 等待得到收到分组数据
modifiedSentence = clientSocket.recv(1024)
print('From Server:', modifiedSentence.decode())
# 关闭套接字、进程
clientSocket.close()
"""
python3
TCPServer.py
"""
from socket import *
serverPort = 12000 # 服务器端口号
# 创建服务器套接字
serverSocket = socket(AF_INET, SOCK_STREAM) # (地址簇=底层使用IPv4, 套接字类型=TCP套接字)
# 绑定端口号与服务器套接字
serverSocket.bind(('', serverPort))
# 聆听TCP连接请求
serverSocket.listen(1)
print('The server is ready to receive')
while True:
# 等待得到收到信息(TCP连接套接字, 源地址)
connectionSocket, addr = serverSocket.accept()
sentence = connectionSocket.recv(1024).decode()
print("Have received message:", sentence)
capitalizedSentence = sentence.upper()
# 发送报文
connectionSocket.send(capitalizedSentence.encode())
# 关闭TCP连接套接字
connectionSocket.close()
先启动服务器端,必须先运行服务器端,不然客户端无法建立TCP连接
再启动客户端
在客户端输入一串小写字母,并回车
结果