使用网络调试助手NetAssist,完成下面测试,需要的请留下邮箱
IP
IP是internet protocol(网际互联协议)的缩写,是TCP/IP体系中的网络层协议。
简单来说IP的目的是,用来标记网络上的一台电脑,每个数据包中,都会携带源IP地址和目标IP地址。
查看网卡信息
- linux中 ifconfig
- windows中 ipconfig
IP地址分类
IPv4 已经用完了,目前在推广IPv6,为啥没有IPv5?因为实验阶段就失败了,直接跳到IPv6.
端口
如果把IP比作一间房子,端口就是出入这间房子的门。真正的房子只有几个门,但一个IP地址的端口可以有65536(2^16)之多,端口是通过端口号来标记的,端口号只有整数,范围从0~65535。
端口的分类
-
知名端口(well know ports),范围0~1023
- 80端口分配给HTTP服务
- 21端口分配给FTP服务
-
动态端口,范围1024~65535
动态端口在程序启动的时候计算机会自动分配
socket 简介
TCP/IP协议
TCP/IP协议是Transmission Control Protocol/Internet Protocol的简写,即传输控制协议和因特网互联协议,又名网络通讯协议,是internet最基本的协议、internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。
TCP/IP定义了电子设备如何连入internet,以及数据如何在他们之间传输的标准。协议采用了4层的层级架构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。
TCP/IP网络模型四层模型从根本上和OSI七层网络模型是一样的,只是合并了几层。
socket
socket 又称“套接字”,应用程序通常会通过套接字向网络发送请求或应答网络请求,使主机间或或者一台计算上进程间可以通讯。通俗说:socket就是两个节点为了互相通信,在各自家里装了一步“电话”。
socket使用
- 创建套接字
- 使用套接字收/发数据
- 关闭套接字
"""
UDP 发送数据
"""
import socket
def main():
# 创建套接字,family 是协议族,type是套接字类型
udp_socket = socket.socket(family= socket.AF_INET, type=socket.SOCK_DGRAM)
# 多次发送
while True:
send_data = input('输入发送内容')
# 发送数据
udp_socket.sendto(send_data.encode(), ('192.168.193.48', 8080))
if send_data == 'exit':
break
# 关闭套接字
udp_socket.close()
if __name__ == '__main__':
main()
family是协议族,即IP地址类型,AF_INET对应IPv4,AF_INET6对应IPv6。
type是套接字类型,SCOK_DGRAM是数据报套接字,对应UDP;SOCK_STEAM是流式套接字,对应TCP。
"""
UDP接受数据
"""
import socket
def socket_recv():
# 创建套接字
udp_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
# 绑定本地信息,IP+端口
udp_socket.bind(('', 51624))
# 接受信息,1024表示1KB,返回值为元组(内容,IP)
info = udp_socket.recvfrom(1024)
print('用户:%s发来:%s'% (info[1], info[0].decode()))
udp_socket.close()
def main():
# socket_send()
socket_recv()
if __name__ == '__main__':
main()
同一个端口不能同时被两个软件占用
UDP聊天器
import socket
def socket_send(udp_socket):
send_data = input('输入发送内容')
if send_data == '88':
udp_socket.close()
# 发送数据
udp_socket.sendto(send_data.encode('gbk'), ('192.168.1.112', 8081))
def socket_recv(udp_socket):
info = udp_socket.recvfrom(1024)
print('用户:%s发来:%s'% (info[1], info[0].decode()))
def main():
udp_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
udp_socket.bind(('', 8081))
while True:
try:
socket_send(udp_socket)
socket_recv(udp_socket)
except:
print('88了')
break
if __name__ == '__main__':
main()
TCP介绍
- TCP协议,传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议
- TCP通信需要经过创建连接、数据传送、终止连接三个步骤。
- TCP通信模型中、在通信开始之前,一定要先建立相关连接,才发生数据。
TCP特点
- 面向连接
- 通信双方必须先建立连接才能进行数据传输
- 可靠传输
- TCP采用发送应答机制
- 超时重传
- 错误校验
- 流量控制和阻塞管理
Client & server
server,即服务端,提供服务的一方
client,即客户端,需要被服务的一方
TCP客户端构建流程
- 创建socket
- 连接服务器
- 接受数据(最大接受1024个字节=1KB)
- 发送数据
- 关闭套接字
import socket
def tcp_create():
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_socket.connect(('192.168.1.112', 8080))
return tcp_socket
def tcp_send(link):
send_data = input('输入要发送的数据')
link.send(send_data.encode('gbk'))
def tcp_recv(link):
rec_data = link.recv(1024)
print(rec_data.decode('gbk'))
def main():
link = tcp_create()
# 接收数据
tcp_recv(link)
# 发送
tcp_send(link)
link.close()
if __name__ == '__main__':
main()
TCP服务端
- socket创建套接字
- bind绑定IP和port
- listen使套接字变为可以被动链接
- accept等待客户端的链接
- recv/send接收发送数据
import socket
def create_socket():
# 创建套接字
tcp_ser = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 绑定IP和port
tcp_ser.bind(('', 8081))
# 变为被动连接,监听
tcp_ser.listen(128)
# 等待客户端的连接
new_socket, new_client = tcp_ser.accept()
# 返回原套接字和新套接字对象
return tcp_ser, new_socket
def rec_info(new_socket):
# 接受来自客户端的数据
rec_data = new_socket.recv(1024)
print(rec_data.decode('gbk'))
def send_info(new_socket):
# 回复客户端数据
new_socket.send('因缺思厅'.encode('gbk'))
def main():
tcp_ser, new_socket = create_socket()
rec_info(new_socket)
send_info(new_socket)
new_socket.close()
tcp_ser.close()
if __name__ == '__main__':
main()
绑定多个端口
import socket
def create_socket():
# 创建套接字
tcp_ser = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 绑定IP和port
tcp_ser.bind(('', 8081))
return tcp_ser
def more_client(tcp_ser):
# 变为被动连接,监听
tcp_ser.listen(128)
# 等待客户端的连接
new_socket, client_address = tcp_ser.accept()
# 返回新套接字对象
return new_socket
def main():
tcp_ser = create_socket()
# 多个服务端可以同时连接,但一次只能为一个服务
while True:
new_socket = more_client(tcp_ser)
# print(new_socket)
while True:
rec_info = new_socket.recv(1024)
if rec_info.decode('gbk'):
new_socket.send(b'i am here')
else:
break
new_socket.close()
# tcp_ser.close()
if __name__ == '__main__':
main()
文件下载器
TCP客户端
- 创建套接字
- 目的信息 服务器的ip port
- 连接服务器
- 输入要下载的文件名称
- 发送文件下载请求
- 接收对方发送过来的数据
- 接收到数据在创建文件
- 关闭套接字
import socket
def main():
file_socket_down = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
file_socket_down.connect(('192.168.1.112', 8081))
file_name = input('输入文件名')
file_socket_down.send(file_name.encode('gbk'))
rec = file_socket_down.recv(1024*1024)
if rec:
with open(file_name, 'wb') as f:
f.write(rec)
file_socket_down.close()
if __name__ == '__main__':
main()
TCP服务端
- socket创建套接字
- bind绑定IP和port
- listen使套接字变为可以被动链接
- accept等待客户端的链接
- recv/send接收发送数据
import socket
def send_file(new_socket):
file_name = new_socket.recv(1024).decode()
content = ''
try:
with open(file_name+'1', 'rb') as f:
content = f.read()
except TypeError:
print('no file')
new_socket.send(content)
new_socket.close()
def main():
file_resp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
file_resp.bind(('', 8081))
file_resp.listen(128)
new_socket, new_address = file_resp.accept()
send_file(new_socket)
file_resp.close()
if __name__ == '__main__':
main()
TCP与UDP区别总结
- TCP面向连接;UDP是无连接的,即发送数据之前无需建立连接
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,既不保证可靠交付。
- UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高要求的通信或广播通信。
- 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
- TCP对系统资源要求较多,UDP对系统资源要求较少。