网络通信概述
什么是⽹络
⽹络就是⼀种辅助双⽅或者多⽅能够连接在⼀起的⼯具
如果没有⽹络可想 单机 的世界是多么的孤单
使⽤⽹络的⽬的
联通多⽅然后进⾏通信⽤的,即把数据从⼀⽅传递给另外⼀⽅
⽤⽹络能够把多⽅链接在⼀起,然后可以进⾏数据传递
⽹络编程就是,让在不同的电脑上的软件能够进⾏数据传递,即进程之间的通信
TCP/IP协议
什么是协议
有的说英语,有的说中⽂,有的说德语,说同⼀种语⾔的⼈可以交流,不同的语⾔之间就不⾏了 为了解决不同种族⼈之间的语⾔沟通障碍,现规定国际通⽤语⾔是英语,这就是⼀个规定,这就是协议.
⽹络通信协议是什么
问题: 不同种类之间的计算机到底是怎么进⾏数据传递的呢?
就像说不同语⾔的⼈沟通⼀样,只要有⼀种⼤家都认可都遵守的协议即可, 那么这个计算机都遵守的⽹络通信协议叫做 TCP/IP协议
TCP/IP协议(族)
互联⽹协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP 协议,所以,⼤家把互联⽹的协议简称TCP/IP协议
IP地址
地址就是⽤来标记地点的
ip地址:⽤来在⽹络中标记⼀台电脑的⼀串数字,⽐如192.168.1.1;在本地 局域⽹上是惟⼀的。
IP地址的分类
每⼀个IP地址包括两部分:⽹络地址和主机地址
私有IP
⽹络IP中,国际规定有⼀部分IP地址是⽤于局域⽹使⽤,也 就是属于私⽹IP,不在公⽹中使⽤的,它们的范围是:
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255
回环地址IP
IP地址127.0.0.1 代表本机IP地址,等价于localhost, ⽤ http://127.0.0.1 就可以测试本机中配置的Web服务器。
⼦⽹掩码
⼦⽹掩码不能单独存在,它必须结合IP地址⼀起使⽤。
⼦⽹掩码的作⽤: 将某个IP地址划分成⽹络地址和主机地址两部分. ⼦⽹掩码的设定 必须遵循⼀定的规则, 用来判断两个IP是否在同一个网络。
A: 172.25.254.18/24
B: 172.25.0.10/24
A和B不在一个网段,不能直接通信
端⼝
端⼝就好⼀个房⼦的⻔,是出⼊这间房⼦的必经之路。
端⼝号只有整数,范围是从0到65535;
常见的服务及对应的端口号:
HTTP:80
HTTPS:443
FTP:21
SSH:22
redis:6378
MySql:3306
socket编程
本地进程间通信(IPC)
- 队列
- 同步(互斥锁、条件变量等)
- 管道
⽹络进程间通信
问题: 本地通过进程PID来唯⼀标识⼀个进程,在⽹络中如何唯⼀标识⼀个进程?
⽹络层的“IP地址”可以唯⼀标识⽹络中的主机,⽽传输层的“协议+端⼝”可以唯⼀标识主机中的应⽤程序(进程)。因此利用IP地址,协议,端⼝就可以标识⽹络的进程。
什么是socket
socket(简称套接字) 是进程间通信的⼀种⽅式, 能实现不同主机间的进程间通信,我们⽹络上各种各样的服务⼤多都是基于 Socket 来完成通信的。
创建socket
在 Python 中 使⽤socket 模块的函数 socket 就可以完成: socket.socket(AddressFamily, Type)
1). Address Family:
AF_INET: IPV4⽤于 Internet 进程间通信
AF_INET6: IPV6⽤于 Internet 进程间通信
2). Type:套接字类型
SOCK_STREAM: 流式套接字,主要⽤于 TCP 协议
SOCK_DGRAM: 数据报套接字,主要⽤于 UDP 协 议
# encoding=utf-8
"""
Date:2019-07-23 09:55
User:LiYu
Email:liyu_5498@163.com
"""
import socket
# 创建socket对象
# AF_INET:ipv4 AF_INET6:ipv6 =====网络缯协议
# SOCK_STREAM:TCP SOCK_DGRAM:UDP ======传输层协议
tcpSocketObj = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
udpSocketObj = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
UDP介绍
UDP是⼀种⾯向⽆连接的协议,每个数据报都是⼀个独⽴的信息,包括完整 的源地址或⽬的地址,它在⽹络上以任何可能的路径传往⽬的地,因此能否到达⽬的地,到达⽬的地的时间以及内容的正确性都是不能被保证的。
UDP特点
UDP是⾯向⽆连接的通讯协议,UDP数据包括⽬的端⼝号和源端⼝号信息, 由于通讯不需要连接,所以可以实现⼴播发送。 UDP传输数据时有⼤⼩限 制,每个被传输的数据报必须限定在64KB之内。 UDP是⼀个不可靠的协 议,发送⽅所发送的数据报并不⼀定以相同的次序到达接收⽅。
UDP应用场景
UDP是⾯向消息的协议,通信时不需要建⽴连接,数据的传输⾃然是不可靠 的,UDP⼀般⽤于多点通信和实时的数据业务,⽐如:
- 语⾳⼴播
- 视频
- TFTP(简单⽂件传送)
- SNMP(简单⽹络管理协议)
- DNS(域名解释)
UDP⽹络程序
UDP⽹络程序: 服务器端
# encoding=utf-8
"""
Date:2019-07-23 10:43
User:LiYu
Email:liyu_5498@163.com
"""
import socket
import os
udpServer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定IP和端口
# 0.0.0.0代表开放本机的所有IP地址
udpServer.bind(('0.0.0.0', 9001))
print('等待client连接......')
while True:
recvdata, address = udpServer.recvfrom(1024)
cmd = recvdata.decode('utf-8')
if cmd == 'quit':
udpServer.sendto(b'quit', address)
break
print('client[%s]>> %s' % (address[0], cmd))
result = os.popen(cmd)
# print(result.read())
udpServer.sendto(result.read().encode('utf-8'), address)
udpServer.close()
UDP⽹络程序: 客户主机端
# encoding=utf-8
"""
Date:2019-07-23 10:48
User:LiYu
Email:liyu_5498@163.com
"""
import socket
udpClient = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udpClient.sendto(b'hello server', ('172.25.254.28', 9001))
recvdata, address = udpClient.recvfrom(1024)
print('收到server[%s]的消息:%s' % (address[0], recvdata.decode('utf-8')))
udpClient.close()
UDP⽹络程序
TCP介绍
TCP: 传输控制协议(英语:Transmission Control Protocol,缩写为TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP⽹络程序
TCP⽹络程序-server主机
import socket
# 1. 创建服务端socket对象
server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 2. 绑定地址和端口(IP:port)
server.bind(('0.0.0.0', 9998))
# 3. 监听是否有客户端连接?listen
server.listen(5)
print('server start .........')
# 4.接收客户端的连接accept
clientSocketObj, clientAddress = server.accept()
# 5. 接收客户端发送的消息
recv_data = clientSocketObj.recv(1024).decode('utf-8')
print("接收到客户端发送的消息:", recv_data)
# 6. 给客户端发送消息
send_data = b'hello client'
clientSocketObj.send(send_data)
# 7. 关闭socket对象
clientSocketObj.close()
server.close()
TCP⽹络程序-client主机
import socket
# 1. 创建服务端socket对象
client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 2. 连接服务端
client.connect(('172.25.254.197', 9998))
# 3.给服务端发送消息
client.send(b'hello server')
# 4. 接收服务端发送的消息
recv_data = client.recv(1024).decode('utf-8')
print("接收服务端发送的消息:", recv_data)
# 5. 关闭socket对象
client.close()
TCP/UDP对比表格
TCP三次握手、四次挥手详解
TCP三次握⼿
两个包: 同步序列标号 SYN 确认包 ACK
四种状态: SYN_SENT(发送), LISTEN(监听), SYN_RECV(答复), ESTABLISHED(建立连接)
在三次握手中,客户端和服务器端都发送两个包SYN和ACK,只不过服务器端的两个包是一次性发过来的,客户端的两个包是分两次发送的。
TCP数据传输
TCP四次挥手
两个包: FIN:Finish, ACK确认序号
并发服务器
并发服务器是socket应用编程中最常见的应用模型。根据连接方式分为长连接和短连接.
同步是客户端发送请求给服务器等待服务器返回处理结果;
异步是指客户端发送请求给服务器,不等待服务器返回处理结果,而直接去完成其他的流程, 对于处理结果,客户端可以事后查询和让服务器进行主动通知。
单进程服务器
同⼀时刻只能为⼀个客户进⾏服务,不能同时为多个客户服务
类似于找⼀个“明星”签字⼀样,客户需要耐⼼等待才可以获取到服务
多进程服务器
优点: 通过为每个客户端创建⼀个进程的⽅式,能够同时为多个客户端进⾏服务
缺点: 当客户端不是特别多的时候,这种⽅式还⾏,如果有⼏百上千个,就不 可取了,因为每次创建进程等过程需要好较⼤的资源
多线程服务器
# encoding=utf-8
"""
Date:2019-07-23 14:01
User:LiYu
Email:liyu_5498@163.com
"""
import socket
import threading
def task(clientSocketObj, clientAddress):
print('client[%s]连接成功' % clientAddress[0])
while True:
recvData = clientSocketObj.recv(1024)
if recvData.decode('utf-8') == 'quit':
print('client[%s]断开连接' % clientAddress[0])
clientSocketObj.send(b'quit')
break
print('client[%s] to server:>>%s' % (clientAddress[0], recvData.decode('utf-8')))
sendData = input('server to client[%s]:>> ' % clientAddress[0]).encode('utf-8')
clientSocketObj.send(sendData)
clientSocketObj.close()
# server.close()
if __name__ == '__main__':
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 9001))
# 监听
server.listen(5)
print('server已开启')
ts = []
while True:
clientSocketObj, clientAddress = server.accept()
if clientSocketObj:
t = threading.Thread(target=task, args=(clientSocketObj, clientAddress))
ts.append(t)
t.start()
协程版-TCP服务器