Socket |
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)
socket和file的区别:
- file模块是针对某个指定文件进行【打开】【读写】【关闭】
- socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】
利用socket实现简单双人对话场景
import socket ip_port = ('127.0.0.1',9999) sk = socket.socket() sk.bind(ip_port) sk.listen(5) # 最大允许连接5个? while True: print ('server waiting...') conn,addr = sk.accept() ##等待用户连接操作,addr表示获取客户端的ip和端口 conn表示生成实例 while True: try: client_data = conn.recv(1024) # 阻塞状态 接受客户端的数据 1024代表字节 # if not client_data.decode():break print (str(client_data,'utf-8')) A=input('>>>:') conn.sendall(bytes(bytes(A,'utf8'))) except Exception: print("error") break
import socket ip_port = ('127.0.0.1',9999) sk = socket.socket() sk.connect(ip_port) while True: user_input = input('>>:'.strip()) sk.sendall(bytes(user_input,'utf-8')) server_reply = sk.recv(1024) print (str(server_reply,'utf-8'))
注意 上面socket server 的recv接受的不是字节 是字符
通过socket实现ssh的功能以及大数据的传输:
# 一些简单的命令,可直接通过socket传入,如果一些返回结果数据较多的命令,不做处理的话,返回的消息就会错乱
linux_socket_server
#!/usr/bin/env python3.5 # Auth -chenjinpeng- import socket,subprocess,time Ip_port = ('127.0.0.1',9999) Ftp = socket.socket() Ftp.bind(Ip_port) Ftp.listen(5) # 最大允许连5个? while True: print ("server waiting...") conn,addr = Ftp.accept() #等待用户连接操作,addr表示获取客户端的ip和端口 conn表示生成实例 while True: #try: client_data = conn.recv(1024) # 收客户端的消息 阻塞 if not client_data:break # 如果接受不到消息 则退出循环 cmd = client_data.decode().strip() # 将获取到的消息进行转码,将bytes转换为str用decode cmd_call = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE) # 将读取到的命令通过管道符进行输出到变量 #Server_input = input("S >>>:").strip() cmd_result = cmd_call.stdout.read() # 获取命令的结果(此执行结果为bytes类型) if len(cmd_result) == 0: cmd_result = b"cmd execution has no output!" cmd_len=bytes(str("cmd_long|%s"%str(len(cmd_result))),'utf8') # 第一次首先将结果的长度发过去 conn.sendall(cmd_len) ack=conn.recv(50) # 确认用户收到后回复。进行下一步操作 if ack: if ack.decode() == "ack": conn.sendall(cmd_result) # 因为为bytes类型 直接发送 else:break conn.close()
linux_csocket_client
#!/usr/bin/env python3.5 # - Auth chenjinpeng - import socket Ip_port = ('127.0.0.1',9999) Client = socket.socket() Client.connect(Ip_port) #Client.sendall(bytes('请求占领地球','utf8')) #Server_reply = Client.recv(1024) #print (str(Server_reply,'utf8')) while True: User_input = input(">>>:").strip() if len(User_input) == 0:continue if User_input == 'q':break Client.sendall(bytes(User_input,'utf8')) cmd_result_msg=Client.recv(100) # 第一次接受的是服务器发来的字符串长度 cmd_result_len=str(cmd_result_msg.decode()) # 转换str cmd_result_len_result=cmd_result_len.split("|") # 分割列表 if cmd_result_len_result[0] == "cmd_long": # 判断是否是分割的数据 cmd_result_size = int(cmd_result_len_result[1]) # 取出返回的字符长度 else: print ("error !") continue Client.sendall(bytes("ack",'utf8')) # 发送ack确认消息,服务端正式开始发送数据 cmd_len_default=0 # 定义输出读取的字符长度 res = '' # 定义空字符 循环增加每次读取的字符 while cmd_len_default < cmd_result_size: # 判断字符是否读完。如果小于服务端发送过来的长度,则代表没接收完 Server_reply = Client.recv(500) # 每次收取500字符 cmd_len_default+=len(Server_reply) # 每次字符长度加上已经读取的字符长度 res += str(Server_reply.decode()) # 读取过的字符相加,循环完毕后统一打印 else: print (res) print ("-------last time-----") Client.close()