1.socket套接字的原理和应用
- 简单的server1和client1
#服务器与客户端建立方式不同 #网络连接的主要操作就是接受recv和发送send,python3里网络传输只能用byte #recv(128)表示一次传输的最大容量,如果传输的内容过大,需要多次recv(128)才可以接受完。即使过大,每次不一定按照128进行最大传输 import socket s=socket.socket() #建立一个套接字网络单位 #网络连接的host名称和端口需要一致才可以 host=socket.gethostname() port=1234 s.bind((host,port)) #bind绑定,说明这是服务器 #最多监听的客户端数量 s.listen(5) while True: #一个网络单位(服务器)可以有多个客户端连接 c,addr=s.accept() #这是客户端连接时才执行,返回连接和地址 data = c.recv(1024) #服务器连接后接受到的客户端内容 print("server get data:",data) print("Got connection from",addr) #服务器两次发送信息,客户端也需要两次接受 c.send("Thank you for connecting".encode()) #str需要转成比特 c.send(data) #发送接受到的信息,原本就是byte c.close() #--------------------------------------------------------------------------------- import socket s=socket.socket() #建立一个套接字网络单位 # host=socket.gethostname() # port=1234 host=socket.gethostname() port=1234 #s网络单位进行connect连接,说明这是客户端 s.connect((host,port)) #向服务器发送信息,需要变成byte s.send("This is client".encode()) #由于客户端发送了两次信息,需要两次接受 print(s.recv(1024).decode()) #把比特数据转成str print(s.recv(1024).decode()) #把比特数据转成str print(s.recv(1024).decode()) #把比特数据转成str print(s.recv(1024).decode()) #把比特数据转成str
- 简单的server2和client2
import socket ,os,time server = socket.socket() server.bind(('localhost',9999) ) server.listen() while True: conn, addr = server.accept() print("new conn:",addr) while True: print("等待新指令") # recv(128)表示一次传输的最大容量,如果传输的内容过大,需要多次recv(128)才可以接受完 data = conn.recv(128) if not data: print("客户端已断开") break print("执行指令:",data) cmd_res = os.popen(data.decode()).read() #接受字符串,执行结果也是字符串 print("before send",len(cmd_res)) if len(cmd_res) ==0: cmd_res = "cmd has no output..." # 先发内容的byte大小给客户端,用于处理传输内容大于通道时的情况 conn.send( str(len(cmd_res.encode())).encode("utf-8") ) time.sleep(0.5) conn.send(cmd_res.encode("utf-8")) print("send done") # os.path.isfile() # os.stat("sock") server.close() #--------------------------------------------------------------------------------- import socket client = socket.socket() #client.connect(('192.168.16.200',9999)) client.connect(('localhost',9999)) while True: cmd = input(">>:").strip() if len(cmd) == 0: continue client.send(cmd.encode("utf-8")) ##第一次接受内容命令结果的长度,byte数据 cmd_res_size = client.recv(128) print("命令结果大小:",cmd_res_size) received_size = 0 received_data = b'' TotalSize=int(cmd_res_size.decode()) #byte数据转成整数 #开始接受内容 while received_size < TotalSize : data = client.recv(128) # 每次收到的有可能小于1024,所以必须用len判断,返回的是byte长度 received_size += len(data) print("接受内容的长度:",len(data)) #print("接受的内容:",data) #分段打印有时候打印不出来,因为分段格式有时不完整 received_data += data else: print("cmd res receive done...",received_size) print(received_data.decode()) client.close()
server2 and client2 - 结合select的服务器
import socket,select s=socket.socket() host=socket.gethostname() port=1234 s.bind((host,port)) s.listen(5) Inputs=[s] while True: rs,ws,es=select.select(Inputs,[],[]) for r in rs: if r is s: conn,addr=s.accept() print("Got Connection From",addr) Inputs.append(conn) else: try: data=r.recv(1024) disconnected=not data except socket.error: disconnected=True if disconnected: print(r.getpeername(),"disconnected") Inputs.remove(r) else: print(data)
socket and select
2.读取网站
import urllib.request as class_url #返回一个可以读取的对象 webaddress="http://www.python.org" webpage=class_url.urlopen(webaddress) import re text=webpage.read() m=re.search(b'<a href="([^"]+)" .*?>about</a>',text,re.IGNORECASE) #正则表达式 print(m.group()) #获取远程文件 class_url.urlretrieve(webaddress,"download.html") #class_url.urlcleanup() #上面不指定位置才需要用urllib.request
3.可并发的socketserver服务器
可并发的服务器