python开发socket套接字:套接字&通信循环&链接循环&模拟远程命令
一,套接字
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束
socket()模块函数用法
1 1 import socket 2 2 socket.socket(socket_family,socket_type,protocal=0) 3 3 socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默认值为 0。 4 4 5 5 获取tcp/ip套接字 6 6 tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 7 8 8 获取udp/ip套接字 9 9 udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 10 10 11 11 由于 socket 模块中有太多的属性。我们在这里破例使用了'from module import *'语句。使用 'from socket import *',我们就把 socket 模块里的所有属性都带到我们的命名空间里了,
这样能 大幅减短我们的代码。 12 12 例如tcpSock = socket(AF_INET, SOCK_STREAM)
1.服务端套接字函数
s.bind() 绑定(主机,端口号)到套接字
s.listen() 开始TCP监听
s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来
2.客户端套接字函数
s.connect() 主动初始化TCP服务器连接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
3.公共用途的套接字函数
s.recv() 接收TCP数据
s.send() 发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发
s.close() 关闭套接字
二,通信循环
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 客户端 5 #有可能出现端口重用 6 import socket 7 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 8 phone.connect(('192.168.1.114',8081)) #绑定手机卡 9 10 #发,收消息 11 while True: 12 msg=input('>>: ').strip() 13 if not msg:continue 14 phone.send(msg.encode('utf-8')) 15 print('--->has send') 16 data=phone.recv(1024) 17 print('server back res:<%s>' %data) 18 print(type(data)) 19 print(data.decode('utf-8')) 20 print(type(data)) #可以 21 22 phone.close() 23 24 25 26 服务器端 27 #有可能出现端口重用 28 29 import socket 30 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 31 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加,重用这个地址 32 phone.bind(('192.168.1.114',8081)) #绑定手机卡 33 phone.listen(5) #开机 34 35 print('starting...') 36 conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组) 37 print('-------->',conn,client_addr) 38 39 #收,发消息 40 while True:#通信循环 41 data=conn.recv(1024) 42 # print('server has recv') 43 print('client data: <%s>' %data) 44 conn.send(data.upper()) 45 46 conn.close() #挂电话 47 phone.close() #关机
三,链接循环
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 客户端1 5 import socket 6 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 7 phone.connect(('192.168.1.114',8081)) #绑定手机卡 8 9 #发,收消息 10 while True: 11 msg=input('>>: ').strip() 12 if not msg:continue 13 phone.send(msg.encode('utf-8')) 14 data=phone.recv(1024) 15 print('server back res:<%s>' %data) 16 17 phone.close() 18 19 客户端2 20 import socket 21 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 22 phone.connect(('192.168.1.114',8081)) #绑定手机卡 23 24 #发,收消息 25 while True: 26 msg=input('>>: ').strip() 27 if not msg:continue 28 phone.send(msg.encode('utf-8')) 29 data=phone.recv(1024) 30 print('server back res:<%s>' %data) 31 32 phone.close() 33 34 服务器 35 import socket 36 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 37 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 38 phone.bind(('192.168.1.114',8081)) #绑定手机卡 39 phone.listen(5) #开机 40 41 print('starting...') 42 while True: #链接循环 43 conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组) 44 print('-------->',conn,client_addr) 45 46 #收,发消息 47 while True:#通信循环 48 try: 49 data=conn.recv(1024) 50 if not data:break #针对linux 51 print('client data: <%s>' %data) 52 conn.send(data.upper()) 53 except Exception: 54 break 55 conn.close() #挂电话 56 phone.close() #关机
四,模拟ssh
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 客户端 5 import socket 6 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 7 phone.connect(('192.168.20.60',8081)) #绑定手机卡 8 9 #发,收消息 10 while True: 11 msg=input('>>: ').strip() 12 if not msg:continue 13 phone.send(msg.encode('utf-8')) 14 data=phone.recv(1024) 15 print('server back res:<%s>' %data) 16 17 phone.close() 18 19 服务器端 20 import socket 21 import subprocess 22 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 23 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 24 phone.bind(('192.168.1.114',8082)) #绑定手机卡 25 phone.listen(5) #开机 26 27 print('starting...') 28 while True: #链接循环 29 conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组) 30 print('-------->',conn,client_addr) 31 32 #收,发消息 33 while True:#通信循环 34 try: 35 cmd=conn.recv(1024) 36 if not cmd:break #针对linux 37 #执行cmd命令,拿到cmd的结果,结果应该是bytes类型 38 #。。。。 39 res = subprocess.Popen(cmd.decode('utf-8'), shell=True, 40 stdout=subprocess.PIPE, 41 stderr=subprocess.PIPE) 42 stdout=res.stdout.read() 43 stderr=res.stderr.read() 44 45 #发送命令的结果 46 conn.send(stdout+stderr) 47 except Exception: 48 break 49 conn.close() #挂电话 50 phone.close() #关机