python中网络编程基础
一:什么是c\s架构
1.c\s即client\server 客户端\服务端架构.
客户端因特定的请求而联系服务器并发送必要的数据等待服务器的回应最后完成请求
服务端:存在的意义就是等待客户端的请求,服务器无限的运行下去,并不断的处理请求
2.硬件客户端\服务器架构也是c\S架构
客户端\打印机,客户端\存储服务器.......
3.B\S架构即浏览器(browser)\服务端>>>统一接口
二.网络通信:
待续
三.socket网络编程
1.socket中文是指套接字,
1.套接字是计算机网络数据结构它体现的是通信端点的概念,在任何类型的通信之前网络应用程序必须创建套接字
可以将它比作电话插孔,没有它将无法进行通信
2.套接字起源于20世纪70年代加利福尼亚大学伯克利版本UNIX的一部分
套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序与另一个运行的程序进行通信,这就是
所谓的进程间的通信,
3.有两种套接字,
一基于文件的.
AF_UNIX地址家族,又称协议家族
二有面向网络的
AF_INET指因特网,AF_INET6
三socket地址:
1.主机-端口对 ,用于定位服务端主机与应用程序没有它就无法找到服务端的IP,和服务端的应用程序
例子:一个套接字就像一个电话机孔--允许通信一些基础设施,主机与端口号就像区号与电话号码的组合
2.有效端口号:65535(小于1024的端口预留给了系统)
3.python中套接字socket模块的应用'
在socket模块中socket()函数,用于创建socket对象,这些方法都能实现套接字的网络通信
在socket类中socket函数默认是TCP/IP面向连接的AF_INET,类型是SOCK_STREAM数据流的形式.
udpsocket=socket.socket(socket.AF_INET,type=socket.SOCK_STREAM)
socket案例服务端
import socket server = socket.socket() ip_port = ('192.168.15.46',8001) server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #允许地址重用 如果还是报错OSerror,那没办法,改端口 server.bind(ip_port) server.listen() #监听 while 1: conn,addr = server.accept() while 1: server_msg = input('wulaoban>>') server_msg = server_msg.encode('utf-8') conn.send(server_msg) from_client_msg = conn.recv(1024) #1024是一次性最大能接收的消息长度 from_client_msg = from_client_msg.decode('utf-8') if from_client_msg == 'byebye': break print(from_client_msg) conn.close() server.close()
#socket案例tcp客户端
import socket client = socket.socket() server_ip_port = ('192.168.15.46',8001) client.connect(server_ip_port) while 1: from_server_msg = client.recv(1024) from_server_msg = from_server_msg.decode('utf-8') print('来自服务端的消息',from_server_msg) client_msg = input('客户端>>>>') # client_msg = client_msg.encode('utf-8') client.send(client_msg.encode('utf-8')) if client_msg == 'byebye': break client.close()
在socket类中socket函数默认是UDP/IP面向无连接的AF_INET,类型是SOCK_DGRAM数据包的形式.
udpsocket=socket.socket(socket.AF_INET,type=socket.SOCK_DGRAM)
socket案例udp服务端
import socket udp_server = socket.socket(type=socket.SOCK_DGRAM) #datagram 数据包的意思 ip_port = ('192.168.15.46',8001) udp_server.bind(ip_port) print(1111) from_client_msg,client_addr = udp_server.recvfrom(1024) #消息数据类型都是bytes类型,阻塞 print(22222) print(from_client_msg.decode('utf-8')) print(client_addr) udp_server.sendto(b'hello what?',client_addr) udp_server.close()
socket案例udp客户端
import socket udp_client = socket.socket(type=socket.SOCK_DGRAM) server_ip_port = ('192.168.15.46',8001) udp_client.sendto(b'hello',server_ip_port) #c参数1:发送的消息,参数2往哪里发,对方的地址 from_server_msg,server_addr = udp_client.recvfrom(1024) print(from_server_msg.decode('utf-8')) udp_client.close()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #1udp_qq服务端代码 import socket ip_port = ( '127.0.0.1' , 8081 ) #127.0.0.1 本机回环地址,自己玩自己用的 udp_server_sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #DGRAM:datagram 数据报文的意思,象征着UDP协议的通信方式 udp_server_sock.bind(ip_port) #你对外提供服务的端口就是这一个,所有的客户端都是通过这个端口和你进行通信的 while True : qq_msg,addr = udp_server_sock.recvfrom( 1024 ) # 阻塞状态,等待接收消息 print ( '来自[%s:%s]的一条消息:\033[1;44m%s\033[0m' % (addr[ 0 ],addr[ 1 ],qq_msg.decode( 'utf-8' ))) back_msg = input ( '回复消息: ' ).strip() udp_server_sock.sendto(back_msg.encode( 'utf-8' ),addr) #1udp_qq客户端代码 import socket BUFSIZE = 1024 udp_client_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) qq_name_dic = { 'taibai' :( '127.0.0.1' , 8081 ), 'Jedan' :( '127.0.0.1' , 8081 ), 'Jack' :( '127.0.0.1' , 8081 ), 'John' :( '127.0.0.1' , 8081 ), } while True : qq_name = input ( '请选择聊天对象: ' ).strip() while True : msg = input ( '请输入消息,回车发送,输入q结束和他的聊天: ' ).strip() if msg = = 'q' : 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]) # 必须带着自己的地址,这就是UDP不一样的地方,不需要建立连接,但是要带着自己的地址给服务端,否则服务端无法判断是谁给我发的消息,并且不知道该把消息回复到什么地方,因为我们之间没有建立连接通道 back_msg,addr = udp_client_socket.recvfrom(BUFSIZE) # 同样也是阻塞状态,等待接收消息 print ( '来自[%s:%s]的一条消息:\033[1;44m%s\033[0m' % (addr[ 0 ],addr[ 1 ],back_msg.decode( 'utf-8' ))) udp_client_socket.close() |
四.socket案例:
服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | import socket #实例化socket对象 server = socket.socket() #创建了一部手机 ip_port = ( '192.168.15.46' , 8001 ) #买个电话卡 #绑定IP地址和端口 server.bind(ip_port) #插卡 #监听, server.listen() #开机 #等待客户端连接 print ( 111111 ) conn,addr = server.accept() #等别人的电话,阻塞 print ( 222222 ) print (conn) print (addr) #发送消息 # conn.send(b'leihao') #必须是bytes类型的数据 server_msg = input ( '服务端说>>>>' ) conn.send(server_msg.encode( 'utf-8' )) #必须是bytes类型的数据 #接受消息 from_client_msg = conn.recv( 1024 ) #1024,一次性能够接受的消息大小1024B print ( '来自客户端的消息' ,from_client_msg) conn.send(b 'gun' ) #挂电话,关闭通道 conn.close() #关机,关闭socket server.close() |
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import socket client = socket.socket() # #服务端的ip地址和端口 server_ip_port = ( '192.168.15.46' , 8001 ) #连接服务端的应用程序 client.connect(server_ip_port) print ( 'ssss' ) from_server_msg1 = client.recv( 1024 ) #阻塞 print ( 'mmmm' ) print ( '服务端第一条消息:' ,from_server_msg1.decode( 'utf-8' )) client.send(b 'yuema' ) from_server_msg = client.recv( 1024 ) print ( '来自服务端的消息:' ,from_server_msg) client.close() |
加强版的服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | import socket #实例化socket对象 server = socket.socket() #创建了一部手机 ip_port = ( '192.168.15.46' , 8001 ) #买个电话卡 #绑定IP地址和端口 server.bind(ip_port) #插卡 #监听, server.listen() #开机 #等待客户端连接 print ( 111111 ) conn,addr = server.accept() #等别人的电话,阻塞 print ( 222222 ) print (conn) print (addr) #发送消息 # conn.send(b'leihao') #必须是bytes类型的数据 while 1 : server_msg = input ( '王斌>>>>' ) conn.send(server_msg.encode( 'utf-8' )) #必须是bytes类型的数据 #接受消息 from_client_msg = conn.recv( 1024 ) #1024,一次性能够接受的消息大小1024B print ( '来自俊豪妹的消息' ,from_client_msg.decode( 'utf-8' )) # conn.send(b'gun') #挂电话,关闭通道 conn.close() #关机,关闭socket server.close() |
加强版客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import socket client = socket.socket() # #服务端的ip地址和端口 server_ip_port = ( '192.168.15.46' , 8001 ) #连接服务端的应用程序 client.connect(server_ip_port) while 1 : from_server_msg1 = client.recv( 1024 ) #阻塞 print ( '来自王斌消息:' ,from_server_msg1.decode( 'utf-8' )) client_msg = input ( '俊豪妹>>>' ) client.send(client_msg.encode( 'utf-8' )) from_server_msg = client.recv( 1024 ) print ( '来自服务端的消息:' ,from_server_msg) client.close() |
四.面向连接的套接字,与无连接的套接字
1面向连接的套接字必须建立连接,实现这种连接类型的协议是传输控制协议即TCP协议
面向连接的优点:提供序列化,可靠的和不重复的数据交互
缺点,传输效率低
2无连接套接字即是实现这种连接类型的协议是用户数据报协议即UDP
优点:传输效率高
缺点无法保证数据的可靠性
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· 一个基于 .NET 开源免费的异地组网和内网穿透工具
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单