Socket
TCP/IP:(通信)
tcp/ip协议是主机接入互联网以及接入换联网的两台主机通信的标准
实例:
import socket ip_port=('127.0.0.1',9999) #买手机 s=socket.socket() #拨号 s.connect(ip_port) while True: #发消息 send_data=input(">>:") if send_data == '':continue s.send(bytes(send_data,encoding='utf8')) if send_data == 'e':break #收消息 recv_data=s.recv(1024) #挂电话 s.close() socket _client
import socket ip_port=('127.0.0.1',9999) #买手机 s=socket.socket() #买卡 s.bind(ip_port) #开机 s.listen(5) #待机 conn,aad=s.accept() while True: try: #收消息 recv_data=conn.recv(1024) if str(recv_data,encoding='utf8') == 'e':break print(str(recv_data,encoding='utf8')) #发消息 send_data=recv_data conn.send(send_data) except Exception: break #挂电话 conn.close()
单线程:
import socket ip_port=('127.0.0.1',9999) #买手机 s=socket.socket() #买卡 s.bind(ip_port) #开机 s.listen(1) #连接数 while True: #待机 conn,aad=s.accept() while True: try: #收消息 recv_data=conn.recv(1024) if str(recv_data,encoding='utf8') == 'e':break print(str(recv_data,encoding='utf8')) #发消息 send_data=recv_data conn.send(send_data) except Exception: break #挂电话 conn.close()
s.listen(n) 本身可以连接一个,n为挂起连接数
服务端出现端口占用 ,修改端口号即可
粘包问题:若发送大于1024 一次接收不完,被会出现此问题,下一次会打印未接受完的内容
解决办法:先recv()一个长度,写循环接收
具体解决办法如下:
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket import subprocess #导入执行命令模块 ip_port=('127.0.0.1',9999) #定义元祖 #买手机 s=socket.socket() #绑定协议,生成套接字 s.bind(ip_port) #绑定ip+协议+端口:用来唯一标识一个进程,ip_port必须是元组格式 s.listen(5) #定义最大可以挂起胡链接数 #等待电话 while True: #用来重复接收新的链接 conn,addr=s.accept() #接收客户端胡链接请求,返回conn(相当于一个特定胡链接),addr是客户端ip+port #收消息 while True: #用来基于一个链接重复收发消息 try: #捕捉客户端异常关闭(ctrl+c) recv_data=conn.recv(1024) #收消息,阻塞 if len(recv_data) == 0:break #客户端如果退出,服务端将收到空消息,退出 #发消息 p=subprocess.Popen(str(recv_data,encoding='utf8'),shell=True,stdout=subprocess.PIPE) #执行系统命令,windows平 # 台命令的标准输出是gbk编码,需要转换 res=p.stdout.read() #获取标准输出 if len(res) == 0: #执行错误命令,标准输出为空, send_data='cmd err' else: send_data=str(res,encoding='gbk') #命令执行ok,字节gbk---->str---->字节utf-8 send_data=bytes(send_data,encoding='utf8') #解决粘包问题 ready_tag='Ready|%s' %len(send_data) conn.send(bytes(ready_tag,encoding='utf8')) #发送数据长度 feedback=conn.recv(1024) #接收确认信息 feedback=str(feedback,encoding='utf8') if feedback.startswith('Start'): conn.send(send_data) #发送命令的执行结果 except Exception: break #挂电话 conn.close()
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Alex Li import socket ip_port=('127.0.0.1',9999) #买手机 s=socket.socket() #拨号 s.connect(ip_port) #链接服务端,如果服务已经存在一个好的连接,那么挂起 while True: #基于connect建立的连接来循环发送消息 send_data=input(">>: ").strip() if send_data == 'exit':break if len(send_data) == 0:continue s.send(bytes(send_data,encoding='utf8')) #解决粘包问题 ready_tag=s.recv(1024) #收取带数据长度的字节:Ready|9998 ready_tag=str(ready_tag,encoding='utf8') if ready_tag.startswith('Ready'):#Ready|9998 msg_size=int(ready_tag.split('|')[-1]) #获取待接收数据长度 start_tag='Start' s.send(bytes(start_tag,encoding='utf8')) #发送确认信息 #基于已经收到的待接收数据长度,循环接收数据 recv_size=0 recv_msg=b'' while recv_size < msg_size: recv_data=s.recv(1024) recv_msg+=recv_data recv_size+=len(recv_data) print('MSG SIZE %s RECE SIZE %s' %(msg_size,recv_size)) print(str(recv_msg,encoding='utf8')) #挂电话 s.close()
多线程
import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): # print self.request,self.client_address,self.server #conn self.request.sendall(bytes('欢迎致电 10086,请输入1xxx,0转人工服务.',encoding="utf-8")) while True: data = self.request.recv(1024) print("[%s] says:%s" % (self.client_address,data.decode() )) self.request.sendall(data.upper()) if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('127.0.0.1',8009),MyServer) server.serve_forever()
import socket ip_port=('127.0.0.1',8009) #买手机 s=socket.socket() #拨号 s.connect(ip_port) #发送消息 welcome_msg = s.recv(1024) print("from server:",welcome_msg.decode()) while True: send_data=input(">>: ").strip() if len(send_data) == 0:continue s.send(bytes(send_data,encoding='utf8')) #收消息 recv_data=s.recv(1024) print(str(recv_data,encoding='utf8')) #挂电话 s.close()
多线程ssh:
import socketserver import subprocess class MyServer(socketserver.BaseRequestHandler): def handle(self): # print self.request,self.client_address,self.server self.request.sendall(bytes('欢迎致电 10086,请输入1xxx,0转人工服务.',encoding="utf-8")) while True: data = self.request.recv(1024) if len(data) == 0:break print("[%s] says:%s" % (self.client_address,data.decode() )) #self.request.sendall(data.upper()) cmd = subprocess.Popen(data.decode(),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) cmd_res =cmd.stdout.read() if not cmd_res: cmd_res = cmd.stderr.read() if len(cmd_res) == 0: #cmd has not output cmd_res = bytes("cmd has output",encoding="utf-8") self.request.send(cmd_res ) if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('0.0.0.0',8009),MyServer) server.serve_forever()