十网络编程
Posted blogbo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十网络编程相关的知识,希望对你有一定的参考价值。
引言
两个程序a.py和b.py之间传递一个文件:a.py---------->文件------------>b.py
若在不同的电脑:计算机网盘、qq等,实现两个程序的通信
软件开发的架构
两个程序之间的通讯的应用大致分为两种:
第一种应用类:qq、微信、网盘、优酷这一类是需要安装的桌面应用
第二种是web类:百度、知乎、博客园等使用浏览器访问就可以直接使用的应用
这些应用的本质其实都是两个程序之间的通讯,而这两个分类又对应了两个软件开发的架构
c/s架构
client与sever,客户端与服务器端架构,这种架构是从用户层面(也可以是物理层面)来划分的
这里的客户端一般泛指客户端应用程序exe,程序需要先安装之后,才能在用户的电脑上,对用户的电脑操作系统环境依赖较大
B/s架构
browser与sever,中文意思:浏览器端与服务器端架构,这种架构是从用户层面来划分的
Browser浏览器,其实也是一种client客户端,只是这个客户端不需要安装应用程序,只需在浏览器上通过HTTP请求服务器端相关的资源(网页资源),客户端Browser浏览器就能增删改查
网络基础
一个程序如何在网络上找到另一个程序:ip地址精确到每一台电脑,端口精确到具体的程序
IP地址是指互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),是IP Address的缩写。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)。IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。例:点分十进IP地址(100.4.5.6),实际上是32位二进制数(01100100.00000100.00000101.00000110)。
"端口"是英文port的意译,可以认为是设备与外界通讯交流的出口。
osi七层模型
互联网的本质就是一系列的网络协议,这个协议就叫OSI协议(一系列协议),按照功能不同,分工不同,人为的分层七层,实际上这七层是不存在的,没有这七层的概念,只是认为的划分而已,区分出来的目的只是明白那一层是干什么的
socket概念
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,在设计模式中,Socket其实就是一个门面模式,它把负责的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议
Socket就是一个模块,通过调用模块中已经实现的方法建立两个进程之间的连接和通信,也有人将socket说成ip+port,因为ip是用来标识互联网中的一台主机的位置,而port是用来表示这台机器上的一个应用程序,所以只需要确立了ip和port就能找到一个应用程序,并且使用socket模块来与之通信
基于文件类型的套接字家族
套接字家族的名字:AF_UNIX
unix一切皆文件,基于文件的套接字调用就是底层的文件系统来抓取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
基于网络类型的套接字家族
套接字家族的名字:AF_INET
所有的地址家族中,AF_INET是使用最广泛的,python支持多种地址家族,但是由于我们只关心网络编程,所以大部分时候只使用AF_INET
tcp协议和udp协议
TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接受缓存)、面向字节流,使用TCP的应用:Web浏览器;电子邮件、文件传输程序
UDP(User Datagram Protocol)不可靠的、无法连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面对报文,尽最大努力服务,无拥塞控制,使用UDP的应用:域名系统(DNS);视频流;IP语言(VoIP)
套接字(socket)初使用
基于TCP协议的socket
TCP是基于链接的,必须先启动服务器,然后再启动客户端去链接服务器
#sever端(服务器端) import socket sk = socket.socket() sk.bind((‘127.0.0.1‘,8898)) #把地址绑定到套接字 sk.listen() #监听链接 conn,addr = sk.accept() #接受客户端链接 ret = conn.recv(1024) #接受客户端信息 print(ret) #打印客户端信息 conn.send(b‘hi‘) #向客户端发送信息 conn.close() #关闭客户端套接字 sk.close() #关闭服务器套接字(可选) #client端(客户端) import socket sk = socket.socket() #创建客户套接字 sk.connect((‘127.0.0.1‘,8898)) #尝试连接服务器 sk.send(b‘hello!‘) ret = sk.recv(1024) #对话(发送/接受) print(ret) sk.close() #关闭客户套接字
可能会遇到问题
#加入一条socket配置,重用ip和端口 import socket from socket import SOL_SOCKET,SO_REUSEADDR sk = socket.socket() sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加 sk.bind((‘127.0.0.1‘,8898)) #把地址绑定到套接字 sk.listen() #监听链接 conn,addr = sk.accept() #接受客户端链接 ret = conn.recv(1024) #接收客户端信息 print(ret) #打印客户端信息 conn.send(b‘hi‘) #向客户端发送信息 conn.close() #关闭客户端套接字 sk.close() #关闭服务器套接字(可选)
基于UDP协议的socket
UDP是无链接的,启动服务之后可以直接接收消息,不需要提前建立链接
#sever端(服务器端) import socket udp_sk = socket.socket(type = socket.SOCK_DGRAM) #创建一个服务器的套接字 udp_sk.bind((‘127.0.0.1‘,9000)) #绑定服务器套接字 msg,addr = udp_sk.recvfrom(1024) print(msg) udp_sk.sendto(b‘hi‘,addr) #对话(接受与发送) udp_sk.close() #client端(客户端) import socket ip_port = (‘127.0.0.1‘,9000) udp_sk.sento(b‘hello‘,ip_port) back_msg,addr = udp_sk.recvfrom(1024) print(back_msg.decode(‘utf-8‘),addr)
#qq聊天 import socket ip_port = (‘127.0.0.1‘,8081) #把地址绑定到套接字 udp_server_sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#创造一个服务器套接字 udp_server_sock.bind(ip_port)#绑定服务器套接字 while True: qq_msg,addr = udp_server_sock.recvfrom(1024) print(‘来自[%s:%s]的一条消息: 33[1;44m%s 33[0m‘ %(addr[0],addr[1],qq_msg.decode(‘utf-8‘))) back_msg = input(‘回复消息:‘).strip() udp_server_sock.sendto(back_msg.encode(‘utf-8‘),addr) import socker BUFSIZE = 1024 udp_client_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) qq_name_dic = {‘金老板‘:(‘127.0.0.1‘,8081), ‘哪吒‘:(‘127.0.0.1‘,8081), ‘egg‘:(‘127.0.0.1‘,8081), ‘yuan‘:(‘127.0.0.1‘,8081),} while True: qq_name = input(‘请选择聊天对象:‘).strip() while True: msg = input(‘请输入消息,回车发送,输入q结束和他聊天:‘).strip() if msg == ‘1‘:break if not msg or not qq_name or qq_name not in qq_name_dic:continue udp_client_socket.sendto(msg.encode(‘utf-8‘),qq_name_dic[qq_name]) back_msg,addr = udp_client_socket.recvfrom(BUFSIZE) print(‘来自[%s:%s]的一条消息: 33[1;44m%s 33[0m‘ %(addr[0],addr[1],back_msg.decode(‘utf-8‘))) udp_client_socket.close()
以上是关于十网络编程的主要内容,如果未能解决你的问题,请参考以下文章
VSCode自定义代码片段14——Vue的axios网络请求封装