TCP/IP协议(族)
理解
TCP/IP协议中各类协议的关系
端口
端口号
知名端口
众所周知的端口号,范围从0到1023,可以理解为常用电话号,比如110\10086等
例如80端口分配给HTTP服务
21端口分配给FTP服务
动态端口
不以固定分配某种服务,而是动态分配,当某服务所在进程关闭时,同时释放所占端口
查看端口
netstat -an #查看端口状态
IP地址
概念
在网络上用来标记一台电脑的一串数字,例如:192.168.191.1
每个IP分为两个部分一个为网络号一个为主机号
A类IP地址
一个A类IP地址由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须是“0”,
地址范围1.0.0.1-126.255.255.254
二进制表示为:00000001 00000000 00000000 00000001 - 01111110 11111111 11111111 11111110
可用的A类网络有126个,每个网络能容纳1677214个主机
B类IP地址
一个B类IP地址由2个字节的网络地址和2个字节的主机地址组成,网络地址的最高位必须是“10”,
地址范围128.1.0.1-191.255.255.254
二进制表示为:10000000 00000001 00000000 00000001 - 10111111 11111111 11111111 11111110
可用的B类网络有16384个,每个网络能容纳65534主机
C类IP地址
一个C类IP地址由3字节的网络地址和1字节的主机地址组成,网络地址的最高位必须是“110”
范围192.0.1.1-223.255.255.254
二进制表示为: 11000000 00000000 00000001 00000001 - 11011111 11111111 11111110 11111110
C类网络可达2097152个,每个网络能容纳254个主机
D类地址用于多点广播
D类IP地址第一个字节以“1110”开始,它是一个专门保留的地址。
它并不指向特定的网络,目前这一类地址被用在多点广播(Multicast)中
多点广播地址用来一次寻址一组计算机 s 地址范围224.0.0.1-239.255.255.254
E类IP地址
以“1111”开始,为将来使用保留
E类地址保留,仅作实验和开发用
私有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地址127.0.0.1~127.255.255.255用于回路测试,
如:127.0.0.1可以代表本机IP地址,用http://127.0.0.1
就可以测试本机中配置的Web服务器。
socket(套接字)
socket(简称 套接字
) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:
它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的
例如我们每天浏览网页、QQ 聊天、收发 email 等等
创建socket
在 Python 中 使用socket 模块的函数 socket 就可以完成import socket socket.socket(AddressFamily, Type)
说明:
函数 socket.socket 创建一个 socket,该函数带有两个参数:Address Family:
可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用 AF_INETType:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)
创建一个tcp socket(tcp套接字)
import socket # 创建tcp的套接字 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # ...这里是使用套接字的功能(省略)... # 不用的时候,关闭套接字 s.close()
创建一个udp socket(udp套接字)
import socket # 创建udp的套接字 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # ...这里是使用套接字的功能(省略)... # 不用的时候,关闭套接字 s.close()
UDP网络程序收发数据过程
1.创建客户端套接字UDP收发数据demo
#coding=utf-8
from socket import *
# 1. 创建udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)
# 2. 准备接收方的地址
dest_addr = ('192.168.236.129', 8080)
# 3. 从键盘获取数据
send_data = input("请输入要发送的数据:")
# 4. 发送数据到指定的电脑上
udp_socket.sendto(send_data.encode('utf-8'), dest_addr)
# 5. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数
# 6. 显示对方发送的数据
# 接收到的数据recv_data是一个元组
# 第1个元素是对方发送的数据
# 第2个元素是对方的ip和端口
print(recv_data[0].decode('gbk'))
print(recv_data[1])
# 7. 关闭套接字
udp_socket.close()
python3转码
bytes.decode(encoding="utf-8", errors="strict") #解码 str.encode(encoding="utf-8", errors="strict") #编码
注:如果遇到解不了的特殊字符可使用忽略机制 格式:errors="ignore"
TCP相关
TCP理解
TCP三次握手
TCP四次握手
创建一个TPC客户端
流程逻辑:创建socket——》根据对应服务器ip与prot建立链接——》发送数据——》关闭socket断开链接
demo
from socket import * # 创建socket tcp_client_socket = socket(AF_INET, SOCK_STREAM) # 目的信息 server_ip = input("请输入服务器ip:") server_port = int(input("请输入服务器port:")) # 链接服务器 tcp_client_socket.connect((server_ip, server_port)) # 提示用户输入数据 send_data = input("请输入要发送的数据:") tcp_client_socket.send(send_data.encode("gbk")) # 接收对方发送过来的数据,最大接收1024个字节 recvData = tcp_client_socket.recv(1024) print('接收到的数据为:', recvData.decode('gbk')) # 关闭套接字 tcp_client_socket.close()
创建一个TCP服务器端
流程逻辑:创建socket——》绑定本地信息(IP、port)——》使用listen改变socket为被动接收——》当有客户的进行链接时,为其创建单独的socket建立链接——》进行数据交互——》断开生成的socket断开与客户的链接
demo
from socket import * # 创建socket tcp_server_socket = socket(AF_INET, SOCK_STREAM) # 本地信息 address = ('', 7788) # 绑定 tcp_server_socket.bind(address) # 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,这样就可以接收别人的链接了 tcp_server_socket.listen(128) # 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务 # client_socket用来为这个客户端服务 # tcp_server_socket就可以省下来专门等待其他新客户端的链接 client_socket, clientAddr = tcp_server_socket.accept() # 接收对方发送过来的数据 recv_data = client_socket.recv(1024) # 接收1024个字节 print('接收到的数据为:', recv_data.decode('gbk')) # 发送一些数据到客户端 client_socket.send("thank you !".encode('gbk')) # 关闭为这个客户端服务的套接字,只要关闭了,就意味着为不能再为这个客户端服务了,如果还需要服务,只能再次重新连接 client_socket.close()
TCP下载器
客户端代码
import socket if __name__ == '__main__': #创建socket tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #与目标服务器构建链接 tcp_client_socket.connect(('192.168.43.148', 1991)) #发送下载目标文件名称 file_name = input('请输入您即将下载文件名称') tcp_client_socket.send(file_name.encode('utf-8')) #接收目标文件 object_content = tcp_client_socket.recv(1024) #新建文件并写入 object_file = open(file_name, 'wb') object_file.write(object_content) #关闭文件 object_file.close() #关闭socket tcp_client_socket.close()
服务器端
import socket if __name__ == '__main__': #创建socket tcp_sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #绑定服务器信息 tcp_sever_socket.bind(('',1991)) #设置listen #将socket转为被动 tcp_sever_socket.listen(5) #print(tcp_sever_socket.accept()) # 测试使用 client_socket, client_prot = tcp_sever_socket.accept() #接收客户端发送信息 recv_data = client_socket.recv(1024) print(recv_data) object_file = recv_data.decode('utf-8') #打开文件 object_content = open(object_file, 'rb') #读取内容 object_txt = object_content.read() #发送内容 client_socket.send(object_txt) #关闭socket client_socket.close() tcp_sever_socket.close()