五 Python之socket网络编程

<1>socket概念

socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。ocket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。

 

建立一个socket必须至少有2端, 一个服务端,一个客户端, 服务端被动等待并接收请求,客户端主动发起请求, 连接建立之后,双方可以互发数据。

 

注:服务端与客户端之间数据的传输均为字符串,注意编码 解码

 <2>简单客服端与客户端通信

client端:

#_*_coding:utf-8_*_
#__author__:"shikai"import socket
client=socket.socket()                     #声明socket类型,并生成socket连接对象
client.connect(("localhost",1234))      #连接服务器IP和端口
while True:cmd=input("输入指令:").strip()client.send(cmd.encode())            #发送消息data=client.recv(1024)                #接收数据print("recv:",data)client.close()

server端:

#!_*_coding:utf-8_*_
#__author__:"shikai"import socket
server=socket.socket()                #声明socket类型,并生成socket连接对象
server.bind(("localhost",1234))     #绑定IP和端口
server.listen()                       #监听
while True:print("开始等电话了")conn,addr=server.accept()          # 阻塞状态  等待连接 (accept回返回两个数据conn和addr)#coon就是客服端连接之后,服务器为其生成的一个连接实例print(conn,addr)while True:print("接电话了")data=conn.recv(1024)             #接收数据print("recv:",data)conn.send(data.upper())         #处理并发送返回  (把小写变成大写)server.close()

sk.bind(address)

  s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。

sk.listen(backlog)

  开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。

      backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5
      这个值不能无限大,因为要在内核中维护连接队列

sk.setblocking(bool)

  是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。

sk.accept()

  接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。

  接收TCP 客户的连接(阻塞式)等待连接的到来

sk.connect(address)

  连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。

sk.connect_ex(address)

  同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061

sk.close()

  关闭套接字

sk.recv(bufsize[,flag])

  接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。

sk.recvfrom(bufsize[.flag])

  与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。

sk.send(string[,flag])

  将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。

sk.sendall(string[,flag])

  将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

      内部通过递归调用send,将所有内容发送出去。

sk.sendto(string[,flag],address)

  将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。

sk.settimeout(timeout)

  设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s )

sk.getpeername()

  返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。

sk.getsockname()

  返回套接字自己的地址。通常是一个元组(ipaddr,port)

sk.fileno()

  套接字的文件描述符

<3>实现多数据批量传输

 按照设定的值每次传输数据最多1024大小,如果要传输的数据大于1024则分批依次传输完成,为防止粘包问题在两次传输之间添加一次确认消息确认即可

 

client端:

#_*_coding:utf-8_*_
#__author__:"shikai"import socket,osclient=socket.socket()
client.connect(("localhost",6969))
while True:cmd=input("输入指令:").strip()if len(cmd)==0:continue                     #入如果长度为0则继续输入client.send(cmd.encode("utf-8"))             #发送的数据      --->1cmd_res_size=client.recv(1024)                #接受的数据长度 (要解码)print("要接收数据大小:",cmd_res_size)client.send("准备接收数据请发送:".encode("utf-8"))received_size=0received_data=b""while received_size < int(cmd_res_size):       #如果接受的长度小于文件本身长度就持续接受data=client.recv(1024)             #接受数据received_size+=len(data)received_data+=dataelse:print("接收最终大小:",received_size)print(received_data.decode())
client.close()

server端:

#_*_coding:utf-8_*_
#__author__:"shikai"#ssh_服务器端
import socket,os
server=socket.socket()
server.bind(("localhost",6969))
server.listen()while True:coon,addr=server.accept()while True:data=coon.recv(1024)         #接收来的数据     ---->1接受命令if not data:       #客户端没有数据发送就断开print("客户端已断开")breakcmd_res=os.popen(data.decode()).read()    #解码发送来的命令,执行结果也是字符串print("传输数据大小:",len(cmd_res.encode()))    #长度编码if len(cmd_res)==0:          #如果client没有输入命令cmd_res="cmd has no output"coon.send(str(len(cmd_res.encode())).encode("utf-8"))        #发送数据大小给客户端(编码成机器语言)client_ack=coon.recv(1024)                        #解决两次发送之间存在的粘包问题print("准备发送数据:",client_ack.decode())coon.send(cmd_res.encode("utf-8"))           #发送的数据(编码成机器识别的utf-8格式)print("send over...")server.close()

  

 <4>socket与文件传输、添加hashlib认证

hashlib产生md5值,认证传输的文件是否唯一,先产生文件md5值作为检查标准,然后依次发送文件md5,最后做对比验证。客户端 实现从服务器现在下载文件,先接收服务器端发送文件md5值,然后依次接收文件md5值在验证文件下载是否正确。

 

#!_*_coding:utf-8_*_
#__author__:"shikai"
#ftp 客户端 (实现从服务器现在下载文件)
import socket,hashlib
client=socket.socket()
client.connect(("localhost",6969))
while True:cmd=input("输入指令:").strip()if len(cmd)==0:continue                    #入如果长度为0则继续输入if cmd.startswith("get"):               #输入get文件名(检查是否以指定字符串开头)
        client.send(cmd.encode())file_size=client.recv(1024)            #接收文件大小file_total_size=int(file_size.decode())client.send(b"ready to recv file")received_size=0filename=cmd.split()[1]             #文件名就是发来数据的第二个f=open(filename+".nwe","wb")  #以二进制写入m=hashlib.md5()while received_size<file_total_size:if file_total_size-received_size>1024:  #要接收的不止一次size=1024else:size=file_total_size-received_sizeprint("the last recv:",size)data=client.recv(size)            #接收文件received_size+=len(data)m.update(data)                    #分次调用接收md5值
            f.write(data)else:md5_nwe=m.hexdigest()server_md5=client.recv(1024)             #接收服务器发送的md5值print("传输完成",file_size,file_total_size)print("两次md5:",md5_nwe,server_md5)f.close()client.close()
client端:
#_*_coding:utf-8_*_
#__author__:"shikai"
#ftp_服务器端   (实现发送文件功能)
import socket,os,hashlib
server=socket.socket()
server.bind(("localhost",6969))
server.listen()while True:coon,addr=server.accept()while True:print("等待新指令:")data=coon.recv(1024)         #接收来的命令要求if not data:       #客户端没有数据发送就断开print("客户端已断开")breakcmd,filename=data.decode().split()  #获取文件名if os.path.isfile(filename):     #判断文件是否存在m = hashlib.md5()f=open(filename,"rb")filesize=os.stat(filename).st_size      #获取文件大小coon.send(str(filesize).encode())        #发送文件大小coon.recv(1024)               #等待客户端确认for line in f:m.update(line)            #分次调用接收md5值
                coon.send(line)#print("file md5:",m.hexdigest())
            f.close()coon.send(m.hexdigest().encode())       #发送md5值确认print("send done.......")server.close()
服务器端:

 

 <5>socketserver多并发

SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进程” 专门负责处理当前客户端的所有请求。

 

ThreadingTCPServer方法实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互。

#_*_coding:utf-8_*_
#__author__:"shikai"import socket
client=socket.socket()                   #声明socket类型,并生成socket连接对象
client.connect(("localhost",6969))      #连接服务器IP和端口
while True:cmd=input("输入指令:").strip()client.send(cmd.encode())            #发送消息
data=client.recv(1024)                #接收数据print("recv:",data)client.close()
client端:
#!_*_coding:utf-8_*_
#__author__:"shikai"import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):def handle(self):while True:try:self.data=self.request.recv(1024).strip()         #接收数据print("{} wrote:".format(self.client_address[0]))print(self.data)self.request.send(self.data.upper())           #将数据转化为大写发送except ConnectionResetError as e:      #抓取连接异常print("err:",e)break
if __name__=="__main__":          #手动执行程序HOST,PORT="localhost",6969#为每个client端创建一个进程或线程server=socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler)    #ThreadingTCPServer 多并发擦操作server.serve_forever()
socketserver

 

 <6>paramiko模块

paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,该模块基于SSH用于连接远程服务器并执行相关操作

1:获得密钥对命令行输入:ssh-keygen

 

安装

pip install paramiko

  

SSHClient  连接远程服务器并执行基本命令

 

基于用户名密码连接:

#_*_coding:utf-8_*_
#__author__:"shikai"import paramiko
ssh=paramiko.SSHClient()      #实例化ssh 客户端
#允许连接不再host 文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())#连接服务器
ssh.connect(hostname="localhost",port=22,username="shikai",password="123")
#执行命令
stdin,stdout,stderr=ssh.exec_command("df")   #返回:标准输入 输出 错误命令三种结果
#获取命令结果
res=stdout.read()
ssh.close()

 

基于公钥密钥连接:

#无需密码远程连接主机(把公钥给主机,自己保存私钥)

#_*_coding:utf-8_*_
#__author__:"shikai"
#无需密码远程连接主机(把公钥给主机,自己保存私钥)
import paramiko
private_key=paramiko.RSAKey.from_private_key_file("id_rsa")    #私钥储存目录ssh=paramiko.SSHClient()
#允许连接不再know_host文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)
#连接主机
ssh.connect(hostname="localhost",port=22,username="shikai",pkey=private_key)
#执行命令
stdin,stdout,sterr=ssh.exec_command("df")          #返回:标准输入 输出 错误命令三种结果
#获取结果
res=stdout.read()
#关闭连接
ssh.close()

  

 

SFTPClient

用于连接远程服务器并执行上传下载

基于用户名密码上传下载:

import paramikotransport = paramiko.Transport(('hostname',22))
transport.connect(username='shikai',password='123')sftp = paramiko.SFTPClient.from_transport(transport)# 将location.py 上传至服务器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')# 将remove_path 下载到本地 local_path
sftp.get('remove_path', 'local_path')transport.close()

基于公钥密钥上传下载:

 

import paramikoprivate_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')  #私钥文件路径transport = paramiko.Transport(('hostname', 22))
transport.connect(username='shikai', pkey=private_key )sftp = paramiko.SFTPClient.from_transport(transport)# 将location.py 上传至服务器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')# 将remove_path 下载到本地 local_path
sftp.get('remove_path', 'local_path')transport.close()

  

 

 

转载于:https://www.cnblogs.com/shikaishikai/p/9574100.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html ie乱码_Java 0基础入门(初识Html)

在学习Java之前&#xff0c;我们需要了解一定的前端知识。毕竟页面才是用户真正看到的&#xff0c;而且也是体现Java后端逻辑结果的地方。学习HTML后&#xff0c;能够制作界面美观大方的静态网站(更复杂的功能需要JavaScript脚本一起来实现)。HTML制作的网页。所需要的Html开发…

live server插件怎么用_分享几个我日常使用的VS Code插件

在这篇文章中&#xff0c;我想介绍一下自己日常使用中最喜欢的Visual Studio Code扩展。大多数时候&#xff0c;我用VS Code编写的是JavaScript应用程序(标准JavaScript、React、Angular、NodeJS……各式各样)。Bracket Pair Colorizer 2这个扩展很不错&#xff0c;可以帮助我搞…

Android应用程序开发

第一章 Android应用初体验 1.1应用基础 activity是Android SDK中Activity类的一个具体实例&#xff0c;负责管理用户与信息屏的交互。 应用的功能是通过编写一个个Activity子类来实现的。 布局定义了一系列用户界面对象以及它们显示在屏幕上的位置。组成布局的定义保存在XML文件…

phonegap

phonegap 框架详解 转自&#xff1a;http://www.cnblogs.com/hubcarl/p/4216844.html首先, 来看一下phonegap 初始化流程以及Native 与 JS 交互流程图。 说明&#xff1a;socket server模式下, phonegap.js 源码实现的采用1 毫秒执行一次XHR请求, 当Native JS 队列里面有JS语…

j2ee核心模式_Operator和Sidecar正在成为软件交付新模式

现如今的开发人员希望可以开发出具备弹性和可扩展的分布式系统。该系统受益于软件复用和开源模型创新&#xff0c;针对安全性问题能够轻易完成补丁更新并进行低风险的升级。该系统不可能通过带有各种嵌入式语言库的应用程序框架来实现。最近&#xff0c;一篇关于“多运行时微服…

微信JS-SDK选择相册或拍照并上传PHP实现

理解&#xff1a;微信上传接口是拍照&#xff0c;或者选择本地照片&#xff0c;上传到微信的服务器&#xff0c;获取到一个id&#xff0c;通过token与这个id获取到图片&#xff0c;保存到服务器即可。 效果 通过微信js接口&#xff0c;调用底层程序。 需要引入js文件&#xff0…

android socket 长连接_TCP/IP,http,socket,长连接,短连接

点击上方蓝色字体&#xff0c;选择“标星公众号”优质文章&#xff0c;第一时间送达上一篇&#xff1a;这300G的Java资料是我师傅当年给我的&#xff0c;免费分享给大家下一篇&#xff1a;这200G的Java实战资料是我师傅当年教我的第二招作者 | ksfzhaohui来源 | my.oschina.net…

二、Python安装扩展库

第一步:推荐easy_install工具 下载地址:https://pypi.python.org/pypi/setuptools 下载"ez_setup.py"文件; 通过运行cmd命令找到ez_setup.py文件所在目录,通过命令[python ez_setup.py]执行安装easy_install 安装成功截图 第二步:安装扩展酷 例如安装"suds"…

ORACLE 10.2.01升级10.2.05 for windows 详细文档

最近要做一个数据库的升级工作&#xff0c;提前在自己的PC机上练习了一下&#xff0c;这种文档在网上很多&#xff0c;但是大多都是使用命令编辑脚本&#xff0c;其实数据库还有一个DBUA的升级工具可以使用&#xff0c;使升级工作方便了很多。 OS环境&#xff1a;windows XP 32…

stm32正交编码器 原理图_恶劣环境下应用的电感式增量编码器和绝对编码器

编码器可分为两种基本类型 - 增量编码器和绝对编码器。增量编码器的显着特征是它报告角度的变化。换句话说&#xff0c;当增量编码器通电时&#xff0c;它不会报告其角位置&#xff0c;直到它具有测量的参考点。绝对编码器明确地在比例或范围内报告其位置。换句话说&#xff0c…

python基础代码的含义_Python基础学习篇

原标题&#xff1a;Python基础学习篇 1、编码 默认情况下&#xff0c;Python 3 源码文件以 UTF-8 编码&#xff0c;所有字符串都是unicode 字符串。 当然你也可以为源码文件指定不同的编码&#xff1a;# -*- coding: cp-1252 -*- 2、标识符 第一个字符必须是字母表中字母或下划…

java面向对象super_【JavaSE】面向对象之super、final

一、super关键字它是一个指代变量&#xff0c;用于在子类中指代父类对象。1.作用指代父类对象区分子父类同名的成员变量&#xff0c;区分父类中成员变量和子类中同名的局部变量2.使用与this相同&#xff0c;调用父类成员变量和成员方法&#xff1a;super.xx super.xxx()调用父类…

mac下的svn服务器建立

MAC下的SVN服务器建立: from : http://blog.csdn.net/q199109106q/article/details/8655204 在Windows环境中&#xff0c;我们一般使用TortoiseSVN来搭建svn环境。在Mac环境下&#xff0c;由于Mac自带了svn的服务器端和客户端功能&#xff0c;所以我们可以在不装任何第三方软件…

php 字符串 替换 最后,php如何替换字符串中的最后一个字符

php替换字符串中的最后一个字符的方法是&#xff1a;可以通过preg_replace()函数来实现。该函数的语法为&#xff1a;【preg_replace(mixed $pattern, mixed $replacement, mixed $subject】。要替换字符串中的最后一个字符&#xff0c;可以通过preg_replace()函数来实现。(如果…

logback的使用和logback.xml详解

原文地址&#xff1a;https://www.cnblogs.com/warking/p/5710303.html#4046335 作者&#xff1a;行走在云端的愚公 一、logback的介绍   Logback是由log4j创始人设计的另一个开源日志组件,官方网站&#xff1a; http://logback.qos.ch。它当前分为下面下个模块&#xff1a; …

tcp协议的主要功能是什么_前端要知道的网络知识一:TCP/IP 协议到底在讲什么...

你之所以不知道那套书在讲什么&#xff0c;是因为你还没有认识到网络协议有什么用&#xff0c;怎么用&#xff0c;以什么形式在使用&#xff0c;网络协议的概念很简单&#xff0c;就几句话&#xff0c;你只知道网络协议的概念&#xff0c;只知道很多大神都推荐这套书&#xff0…

mysql创建定时器(event),查看定时器,打开定时器,设置定时器时间

为什么80%的码农都做不了架构师&#xff1f;>>> 由于项目需要创建定时器&#xff08;evevt&#xff09;&#xff0c;所以就百度了一下&#xff0c;发现基本都是来源于一个模板&#xff0c;有些功能还不全&#xff0c;现在自己总结一下。 注&#xff1a;mysql版本是…

音频视频

1.IOS视频播放代码&#xff08;添加MediaPlayer.framework和#import&#xff09; -(void)playMovie:(NSString *)fileName{//视频文件路径NSString *path [[NSBundle mainBundle] pathForResource:fileName ofType:"mp4"];//视频URLNSURL *url [NSURL fileURLWithP…

linux内核怎么修改屏幕旋转方向_树莓派4—屏幕旋转

配置&#xff1a;树莓派4raspberry pi系统&#xff0c;HDMI显示&#xff0c;非触屏。问题&#xff1a;想将屏幕旋转90&#xff0c;按网上说的&#xff0c;方法一&#xff1a;在config.txt文件中添加display_rotate1&#xff0c;或者添加display_hdmi_rotate1&#xff0c;保存后…

独家直播!阿里移动前端开源框架Weex揭秘

或许你写过了很多行代码&#xff0c;修过许多的bug&#xff0c;学过各种各样的语言&#xff0c;却只在一个最好的时机遇见了他…… 是啥&#xff1f; 敲&#xff01;黑&#xff01;板&#xff01;跟&#xff01;我&#xff01;念&#xff01;Weex&#xff5e;&#xff5e;&…