十九、Python之socket编程
时间:2019-08-09
本文章向大家介绍十九、Python之socket编程,主要包括十九、Python之socket编程使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
socket(套接字)就是建立连接,发送,接收。大部分网络协议都是建立在socket之上的,例如:http,ftp,smtp等等
socket用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过‘套接字’向网络发出请求或者应答网络请求,说白了就是一种通信机制。它类似于银行,电信啊这些部分的电话客服部门。你打电话的时候,那边会分配一个人回答你的问题,客服部门就相当于socket的服务器端了,这边呢就相当于客户端了,在和你通话结束前,如果有人在想找和你通话的那个说话,是不可能的,因为你在和他通信,当然客服部门的电话交换机也不会重新分配。
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open----->读写write/read----->关闭close”模式来操作。Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读写/IO,打开,关闭)。
流程拓扑图:
SocketServer:同时只能接受1个连接,就算listhen改为5还是只能接受1个连接,另一个客户端如果发送数据只能处于等待状态;只有这个客户端断开连接它才能发送数据给服务端
Socket服务器端编程主要包括下面几步:
1. 打开socket
2. 绑定到一个地址和端口
3. 侦听进来的连接
4. 接收数据
5. 读写收据
import socket
HOST = '' #为空代表本机
PORT = 50007
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #打开socket
s.bind((HOST,PORT)) #2 绑定地址和端口,注意里面接一个元组的参数
s.listen(1) #3 1代表同时只能有1个连接
while True:
conn,addr = s.accept() #3 s.accept()返回两个变量,conn返回哪个客户端连接过来,addr返回客户端地址
print 'Connected by',addr
while 1:
data = conn.recv(1024) #4 1024代表1k,是接收的客户端的数据
if not data: #代表客户端已经断开了
break
conn.sendall(data.upper()) #5 把收到的数据改成大写又发回去
conn.close()
以上代码在Linux和mac下面没有问题,但是在Linux里就需要加个异常处理,
捕捉socketError异常。
-----------------------------------------------------------------------------------------------------------------
Socket客户端编程主要包括下面几步:
1.打开socket
2.连接到服务器端的地址和端口
3.读写收据
import socket
HOST = '127.0.0.1'
PORT = 50007
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT)) #2
while True:
msg = input(“>>:”).strip()
if len(msg) == 0:continue
s.sendall(msg)
data = s.recv(1024) #等待服务器的返回,并存储在变量data里
print ‘Received’,data
s.close()
SocketServer实现多并发(能支持100个左右,再大了可能就扛不住了):
有三种方式:分叉,线程,异步IO,下例使用的是线程方式
服务器端:
import SocketServer
class MyTCPHandler(SocketServer,BaseRequistHandler):
while True:
def handle(self): #这个handle函数就是用于处理跟客户端所有的通信
self.data = self.request.recv(1024).strip()
print ("{} wrote:".format(self.client_address[0]))
print (self.data)
self.request.sendall(self.data.upper())
if __name__ == "__main__":
HOST,PORT = "localhost",9999
server = SocketServer.ThreadingTCPServer((HOST,PORT),MyTCPHandler)
server.server_forever()
客户端:
客户端改下端口就行了,对应服务端的9999
SocketServer实现文件传送:目前我们做的是就是客户端发送什么我就给它改成大写返回去,没什么用,这节就是讲让server干点事情
1.客户端发过来的命令我让它执行,模仿puppet,saltstack。。。。。。(但还有很多问题)
服务器端:
import SocketServer
import os
class MyTCPHandler(SocketServer,BaseRequistHandler):
def handle(self): #这个handle函数就是用于处理跟客户端所有的通信
while True:
data = self.request.recv(1024).strip()
cmd_res = os.popen(data).read()
if len(cmd_res)==0:
cmd_res = “cmd has no feedback”
self.request.sendall(data.upper())
if __name__ == "__main__":
HOST,PORT = "localhost",9999
server = SocketServer.ThreadingTCPServer((HOST,PORT),MyTCPHandler)
server.server_forever()
客户端:
import socket
HOST = '127.0.0.1'
PORT = 9999
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT)) #2
while True:
msg = input(“>>:”).strip()
if len(msg) == 0:continue
s.sendall(msg)
data = s.recv(8196) #等待服务器的返回,并存储在变量data里
print ‘Received’,data
s.close()
SocketServer实现ftp雏形:
服务器端:客户端往服务器上传文件目录recv
import SocketServer
import os
class MyTCPHandler(SocketServer,BaseRequistHandler):
def handle(self): #这个handle函数就是用于处理跟客户端所有的通信
while True:
data = self.request.recv(1024).strip()
data=data.split(“|”)
if hasattr(self,data[0]):
func=getattr(self,data[0])
func(data[1:])
def file_transfer(self,msg):
if msg[0] == “get”:
print (“-----going to send file:%s to client ” % msg[1])
filename = msg[1]
if os.path.isfile(filename): #判断客户端发来的请求是否是文件并且存在
filesize = os.path.getsize(filename) #1.判断客户端发来的文件的大小
ack_msg = “file_transfer|get|ready” % file_size #服务器给客户端的应答(如果文件存在的情况)
self.request.send(ack_msg) #执行发送ack_msg给客户端
client_ack = self.request.recv(1024)
print ‘-----à client ack:’,client_ack
if client_ack.startswith(“file_transfer|get|recv|ready”):
f = file(filename,”rb”)
for line in f:
self.request.send(line)
else:
print ‘--------file %s send done-------’ % filename
f.close()
else:
ack_msg = “file_transfer|get|file doesn’t exists” #服务器给客户端的应答(如果文件不存在的情况)
self.request.send(ack_msg)
if __name__ == "__main__":
HOST,PORT = "localhost",9999
server = SocketServer.ThreadingTCPServer((HOST,PORT),MyTCPHandler)
server.server_forever()
客户端:从服务器端下载文件目录recv
import socket
class FTP(object):
def __init__(self,host,port):
self.host = host
self.port = port
def put(self,msg): #定义上传方法,命令为put local_file
def get(self,msg): #定义下载方法,命令为get remote_file
print ‘---->get:’,msg
if len(msg) > 0:
remote_filename=msg[0]
cmd_msg=”file_transfer|get|%s” % remote_filename
self.sock.send(cmd_msg)
feedback = self.sock.recv(1024)
print (‘----->feedback:’,feedback)
if feedback.startswith(“file_transfer|get|read”):
file_size = int(feedback.split(“|”)[-1])
ack_msg = “file_transfer|get|recv|ready”
self.sock.send(ack_msg)
f = file(“recv/%s” % remote_filename,’wb’)
recv_size = 0
while not file_size == recv_size:
if file_size - recv_size > 1024:
data = self.sock.recv(1024)
f.write(data)
recv_size += len(data)
else:
data = self.sock.recv(file_size – recv_size)
recv_size+= file_size - recv_size
f.write(data)
else:
f.close()
print “-----recv file ”
print (feedback)
def list_file(self): #定义查看方法
def interactive(self): #定义交互方法
while True:
user_input = input(“ftp_client::”).strip()
if len(user_input) == 0:continue
cmd = user_input.split()
if hasattr(self,cmd[0]): #这里用到了反射
func = getattr(self,cmd[0])
func(cmd[1:])
else:
print “Wrong cmd usage!”
def connect(self): #定义连接方法
self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.sock.connect((self.host,self.port))
self.interactive()
if __name__ == ‘__main__’:
ftp = FTP(192.168.1.130,9999)
HOST = '192.168.1.130'
PORT = 9999
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT)) #2
while True:
msg = input(“>>:”).strip()
if len(msg) == 0:continue
s.sendall(msg)
data = s.recv(8196) #等待服务器的返回,并存储在变量data里
print ‘Received’,data
s.close()
原文地址:https://www.cnblogs.com/steven9898/p/11329448.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Centos7.4环境安装lamp-php7.0教程
- iOS摄像头推流(2)
- ubuntu 16.04LTS 开机启动自动更换壁纸的实现方法
- linux中Centos7的LVM磁盘扩容问题
- 如何禁止网站内容被搜索引擎收录的几种方法讲解
- Apache由http自动跳转到https的多种方法
- CentOS服务器中安装FFmpeg的完整步骤
- linux中Centos7增加swap分区详解
- CentOS7如何重置root密码的方法
- Linux下RPM打包制作过程
- linux ssh端口转发的三种方式
- 学习Centos7软raid5的挂载
- linux中crw brw lrw等等文件属性是什么
- centos中文件与权限的基本操作教程
- 在Linux中使用tcpdump命令捕获与分析数据包详解