网络编程
基于tcp协议的简单通话
server端
import socket sk =socket.socket() sk.bind(('127.0.0.1',8080)) #绑定卡(设置ip地址端口号) sk.listen() #监听,等待接收电话 conn,addr = sk.accept() #建立连接 while True:
ret =conn.recv(1024).decode('utf-8') if ret == 'bye': break print(ret) info = input('>>>') conn.send(bytes(info.encode('utf-8'))) conn.close() sk.close()
client端
import socket sk = socket.socket() #创建一个链接 sk.connect(('127.0.0.1',8080)) #拨打对方号码(对方端口地址) while True: info = input('>>>') sk.send(bytes(info.encode('utf-8'))) ret = sk.recv(1024).decode('utf-8') print(ret) if ret == 'bye': sk.send(b'bye') break sk.close() #关闭
基于udp的简单通话
server端
import socket sk =socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',8080)) while True: msg,addr = sk.recvfrom(1024) print(addr) print(msg.decode('utf-8')) info = input('>>>') info = ('来自server端的消息:%s'%info).encode('utf-8') sk.sendto(info,addr) sk.close()
client端1
import socket sk = socket.socket(type=socket.SOCK_DGRAM) ip_port = ('127.0.0.1',8080) while True: info = input('小白说:') info = ('来自小白的消息:%s'%info).encode('utf-8') sk.sendto(info,ip_port) msg,addr = sk.recvfrom(1024) print(msg.decode('utf-8')) sk.close()
client端2
import socket sk = socket.socket(type=socket.SOCK_DGRAM) ip_port = ('127.0.0.1',8080) while True: info = input('小黑说:') info = ('来自小黑的消息:%s' % info).encode('utf-8') sk.sendto(info,ip_port) msg,addr = sk.recvfrom(1024) print(msg.decode('utf-8')) sk.close()
黏包现象
基于tcp的黏包现象,但不丢包
server端
import socket sk = socket.socket() sk.bind(('127.0.0.1',8090)) sk.listen() conn,addr = sk.accept() while True: info = input('>>>').encode('utf-8') conn.send(info) ret = conn.recv(1024).decode('utf-8') print(ret) conn.close() sk.close()
client端
import socket import subprocess sk = socket.socket() sk.connect(('127.0.0.1',8090)) while True: cmd = sk.recv(1024).decode('gbk') ret = subprocess.Popen(cmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) std_out = 'stdout:'+(ret.stdout.read()).decode('gbk') print(std_out) std_err = 'stderr:'+(ret.stderr.read()).decode('gbk') print(std_err) sk.send(std_out.encode('utf-8')) sk.send(std_err.encode('utf-8')) sk.close()
基于udp远程下发命令,不黏包,丢包不可靠
server端
import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',8090)) msg,addr = sk.recvfrom(1024) while True: cmd = input('>>>') if cmd =='q': break sk.sendto(cmd.encode('utf-8'),addr) msg,addr = sk.recvfrom(1024) print(msg.decode('utf-8')) sk.close()
client端
import socket import subprocess sk = socket.socket(type=socket.SOCK_DGRAM) addr = ('127.0.0.1',8090) sk.sendto('吃了么'.encode('utf-8'),addr) while True: cmd,addr = sk.recvfrom(1024) ret = subprocess.Popen(cmd.decode('gbk'),shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) std_out = 'stdout:'+(ret.stdout.read()).decode('gbk') print(std_out) std_err = 'stderr:'+(ret.stderr.read()).decode('gbk') print(std_err) sk.sendto(std_out.encode('utf-8'),addr) sk.sendto(std_err.encode('utf-8'),addr) sk.close()
解决黏包问题(方法一):
server端
import socket sk = socket.socket() sk.bind(('127.0.0.1',8090)) sk.listen() conn,addr = sk.accept() while True: cmd = input('>>>') if cmd == 'q': conn.send(b'q') conn.send(cmd.encode('gbk')) num = conn.recv(1024).decode('utf-8') conn.send(b'ok') ret = conn.recv(int(num)).decode('gbk') print(ret) conn.close() sk.close()
client端
import socket import subprocess sk = socket.socket() sk.connect(('127.0.0.1',8090)) while True: cmd = sk.recv(1024).decode('gbk') if cmd == 'q': break ret = subprocess.Popen(cmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) std_out =ret.stdout.read() std_err =ret.stderr.read() sk.send(str(len(std_out)+len(std_err)).encode('utf-8')) sk.recv(1024) #ok sk.send(std_out) sk.send(std_err) sk.close() #好处:确定到底接收多大的数据 #不好的地方:多了一次交互
解决黏包问题(方法二):
引用struct模块
server端
import socket import struct sk = socket.socket() sk.bind(('127.0.0.1',8090)) sk.listen() conn,addr = sk.accept() while True: cmd = input('>>>') if cmd == 'q': conn.send(b'q') conn.send(cmd.encode('gbk')) num = conn.recv(4) #收到要发的数据的长度 num = struct.unpack('i',num)[0] ret = conn.recv(int(num)).decode('gbk') print(ret) conn.close() sk.close()
client端
import socket import subprocess import struct sk = socket.socket() sk.connect(('127.0.0.1',8090)) while True: cmd = sk.recv(1024).decode('gbk') if cmd == 'q': break ret = subprocess.Popen(cmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) std_out =ret.stdout.read() std_err =ret.stderr.read() len_num = len(std_out)+len(std_err) num_by = struct.pack('i',len_num) sk.send(num_by) sk.send(std_out) sk.send(std_err) sk.close()