1、UDP通信编解码类

  (1) 类

 # ------------------UDP通信解码编码类------------------------

 from socket import *

 class My_Socket(socket):
def __init__(self,coding='utf-8'):
self.coding = coding
super(My_Socket, self).__init__(type=SOCK_DGRAM) def my_recv(self,num):
msg,addr = self.recvfrom(num)
return msg.decode(self.coding),addr def my_send(self,msg,addr):
return self.sendto(msg.encode(self.coding),addr)

  (2) UDP通信客户端(调用自己的解码编码类)

# --------------UDP通信客户端(调用自己的解码编码类)-----------------

from MySocket import My_Socket

sk = My_Socket()

msg_s = input('>>>')

sk.my_send(msg_s,('127.0.0.1',8080))

sk.close()

UDP通信客户端(调用自己的解码编码类)

  (3) UDP通信服务器端(调用自己的解码编码类)

 # -----------UDP通信服务器端(调用自己的解码编码类)---------------

 from MySocket import My_Socket

 sk = My_Socket()

 sk.bind(('127.0.0.1',8080))

 msg_r,addr = sk.my_recv(1024)

 print(msg_r)

 sk.close()

UDP通信服务器端(调用自己的解码编码类)

2、文件的上传(服务器端)

  (1)只能上传小文件。

 import socket
import json
sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen(5) conn,addr = sk.accept() # 上传下载的逻辑
str_dic = conn.recv(1024).decode('utf-8')
dic = json.loads(str_dic)
# dic = {'opt':ls.get(num),'filename':filename,'content':content}
if dic['opt'] == 'upload':
filename = 'new_'+dic['filename']
with open(filename,'w',encoding='utf-8') as f:
f.write(dic['content']) conn.close()
sk.close()

只能传小文件(服务器端)

  (2)通过方法:先获取文件大小,然后把文件大小加入到字典中,把字典发过去接收端就可以知道文件大小了,就可以根据文件大小进行接收大文件了。
    问题:可能黏包的问题,就是send了字典之后,就send了文件内容。
    解决的方法:在两个send之间加了一个recv,接收一个success 。

 import socket
import json
sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen(5) conn,addr = sk.accept() # 上传下载的逻辑
str_dic = conn.recv(1024).decode('utf-8')# 先接受到字符串形式的字典
conn.send(b'success')# 给客户端回复一个成功,代表字典接收成功了,也是把字典内容和接下来要接收的文件内容分割开
dic = json.loads(str_dic)# 反序列化,将字典还原出来
# dic = {'opt':ls.get(num),'filename':filename,'content':content}
if dic['opt'] == 'upload':
filename = 'new_'+dic['filename']# 产生一个新的文件名
filesize = dic['filesize']# 获取文件的大小
with open(filename,'wb') as f:
while filesize:
content = conn.recv(1024)
filesize -= len(content)# 减去接收到的长度,而不能直接减去1024
f.write(content) conn.close()
sk.close()

以下解决黏包现象,实现大文件的传输,比较low比的方法

  (3)先把字典的大小获取,然后server先接收字典的大小,然后根据字典大小去接收字典,这样就直接解决了2中的问题。

 import socket
import json
sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen(5) conn,addr = sk.accept() # 我算出来了字典长度为70(属于作弊),这个‘70’是两个字节的长度,所以接收两个字节长度,把字典大小接收到
len_dic = int(conn.recv(2).decode('utf-8'))#在这里转成int以便下一行代码中当做recv的参数
# 这个len_dic = 70,转码后是字符串 str_dic = conn.recv(len_dic).decode('utf-8')# 根据字典长度去接收字典,防止接收到文件的内容 # 在这里,上边代码我明确了字典大小,就可以按照字典大小接收固定长度,这样之后,就可以防止上边接收到 下边应该接收的文件内容
# 此时我就可以省略一个 sk.send(b'success')这句话,就可以少一个网络传输数据时的延时。
dic = json.loads(str_dic)
# dic = {'opt':ls.get(num),'filename':filename,'filesize':filesize}
if dic['opt'] == 'upload':
filename = 'new_'+dic['filename']
filesize = dic['filesize']
with open(filename,'wb') as f:
while filesize:
content = conn.recv(1024)
filesize -= len(content)
f.write(content) conn.close()
sk.close()

比较中端的方法

  (4)字典的大小不固定,所以我使用了struct模块中的pack方法,解决这个事情,使字典的大小这个数字无论多少位,我都固定生成一个4位的bytes,这样server端就可以直接先接收4个字节了,通过unpack获取字典大小。

 import socket
import json
import struct
sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen(5) conn,addr = sk.accept() # 上边说了,如果我在这里明确接收2个字节就可以接收到字典的大小,这是作弊
# 因为字典大小如果是 100~999 ,我这里就要接收3个字节
# 如果字典大小是 100000 ~ 999900 ,我这里就要接收6个字节
# 所以为了公正,我使用了struct,在客户端先把‘字典大小’的长度固定为4个字节
len_dic = conn.recv(4)# 此时接收到了 字典的长度,不过是经过struct.pack处理后的
len_str_dic = struct.unpack('i',len_dic)[0] # 在这里,得到int型的字典长度,注意:unpack方法返回一个元组。 str_dic = conn.recv(len_str_dic).decode('utf-8')# 根据字典长度去接收字典,防止接收到文件的内容 dic = json.loads(str_dic)
# dic = {'opt':ls.get(num),'filename':filename,'filesize':filesize}
if dic['opt'] == 'upload':
filename = 'new_'+dic['filename']
filesize = dic['filesize']
with open(filename,'wb') as f:
while filesize:
content = conn.recv(1024)
filesize -= len(content)
f.write(content) conn.close()
sk.close()

比较高端的方法,使用struct

3、远程执行命令

  (1) 远程执行命令(服务器端)

 # ------------------远程执行命令(服务器端)------------------------

 import socket
import subprocess sk = socket.socket()
sk.bind(("127.0.0.1", 8080))
sk.listen(5) conn, addr = sk.accept() while 1:
cmd = conn.recv(1024).decode('utf-8')
r = subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = r.stdout.read()
stderr = r.stderr.read()
if stdout:
conn.send(stdout)
elif stderr:
conn.send(stderr) conn.close()
sk.close()

远程执行命令(服务器端)

  (2) 远程执行命令(客户端)

 # ---------------远程执行命令(客户端)--------------------

 import socket

 sk = socket.socket()

 sk.connect(('127.0.0.1', 8080))

 while 1:
cmd = input('>>>')
sk.send(cmd.encode('utf-8'))
ret_1 = sk.recv(1024).decode('gbk')
ret_2 = sk.recv(1024).decode('gbk')
print(ret_1) sk.close()

远程执行命令(客户端)

4、黏包

黏包:是指可能是:接收端和发送端两端在进行收发时,数据大小不统一造成的.

也可能是:合包机制和nagle算法的实现,而没有提供科学的拆包机制,造成的.

一种是因为:client连续发送少量数据,时间间隔短,所以nagle算法帮你合包了,但是此时server不知道要接收多少,所以造成数据混乱

一种是因为:client直接发送了大量数据,但是server端接收的长度不够,所以造成数据混乱

  (1) UDP_黏包_服务器

 import socket

 sk = socket.socket(type=socket.SOCK_DGRAM)

 sk.bind(('127.0.0.1', 8080))

 msg, addr = sk.recvfrom(1024)

 print(msg)

 sk.close()

UDP_黏包_客户端

  (2) UDP_黏包_客户端

 import socket
sk = socket.socket(type=socket.SOCK_DGRAM) sk.sendto(b'',('127.0.0.1',8080))
sk.sendto(b'abc',('127.0.0.1',8080))
sk.close()

UDP_黏包_客户端

  (3) TCP_nagle_服务器端

TCP_nagle_服务器端

  (4) TCP_nagle_客户端

 import socket

 BUFSIZE = 1024
ip_port = ('127.0.0.1', 8080) s = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
res = s.connect_ex(ip_port) s.send('hello egg'.encode('utf-8'))

TCP_nagle_客户端

Python_编写UDP通信编解码类、文件的上传、远程执行命令、黏包的更多相关文章

  1. 利用scp 远程上传下载文件/文件夹和ssh远程执行命令

    利用scp传输文件 1.从服务器下载文件scp username@servername:/path/filename /tmp/local_destination例如scp codinglog@192 ...

  2. expect脚本同步文件 expect脚本指定host和要同步的文件 构建文件分发系统 批量远程执行命令

    自动同步文件 #!/usr/bin/expect set " spawn rsync -av root@.txt /tmp/ expect { "yes/no" { se ...

  3. 网络编程 - 1.简单的套接字通信/2.加上通信循环/3.bug修复/4.加上链接循环/5.模拟ssh远程执行命令

    1.简单的套接字通信 服务端 ''' 服务端 接电话 客户端 打电话 1.先启动服务端 2.服务端有两种套接字 1.phone 用来干接收链接的 2.conn 用来干收发消息的 ''' import ...

  4. 使用Struts2实现文件的上传和下载

    (一)单个文件的上传步骤: 1.拷贝jar包:commons-fileupload.jar,  commons-io.jar 下载链接(文件上传.rar):http://www.cnblogs.com ...

  5. 使用xshell软件进行文件的上传和下载

    1.选择xshell的文件里面的属性-->文件传输,把上传路径和下载路径设置好. 上传路径:介绍我们需要向Linux系统里面传东西. 下载路径:就是我们把Linux系统里面的大小拷贝出来. 2. ...

  6. 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件

    [源码下载] 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件 作者:webabcd 介绍重新想象 Windows 8.1 Sto ...

  7. 从零开始编写自己的C#框架(23)——上传组件使用说明

    文章导航 1.前言 2.上传组件功能说明 3.数据库结构 4.上传配置管理 5.上传组件所使用到的类 6.上传组件调用方法 7.效果演示 8.小结 1.前言 本系列所使用的是上传组件是大神July开发 ...

  8. Android中Socket大文件断点上传

    原文:http://blog.csdn.net/shimiso/article/details/8529633 什么是Socket? 所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一 ...

  9. 使用springmvc进行文件的上传和下载

    文件的上传 SpringMVC支持文件上传组件,commons-fileupload,commons-fileupload依赖commons-io组件 配置步骤说明 第一步:导入包 commons-f ...

随机推荐

  1. 使用Navicat for Mysql连接mysql服务器

    使用Navicat for Mysql连接mysql服务器 在windows上用Navicat for Mysql 连接装在虚拟机Ubuntu上的mysql服务器时出现的问题的解决方案. Navica ...

  2. February 12th, 2018 Week 7th Monday

    One man's fault is another man's lesson. 前车之覆,后车之鉴. We make mistakes every day, large or small, fail ...

  3. ubuntu中利用qtcreator引用opencv249及采起采集卡的共享库

    opencv Link:https://github.com/opencv/opencv CqUsbCam link:https://github.com/niuxiaobaoer/CqUsbCam_ ...

  4. DBUtils温习2

    上篇简单回顾了下DBUtils的简介和其常用的类,这篇博客结合C3P0连接池,做一个简单的增删改查操作 1.创建web项目,导入jar包 2.编写c3p0-config.xml和引入工具类 <? ...

  5. 15.scrapy中selenium的应用

    引入 在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值.但是通过观察我们会发现 ...

  6. E - Intervals 贪心

    Chiaki has n intervals and the i-th of them is [li, ri]. She wants to delete some intervals so that ...

  7. SpringMVC Controller 返回值几种类型

    SpringMVC Controller 返回值几种类型 2016年06月21日 19:31:14 为who而生 阅读数:4189 标签: Controller 返回值类型spring mvc 更多 ...

  8. ssm框架的整合搭建(一)

    一个转行菜鸟半年多工作的开始学习历程............ 我是自学,也是我的记录,我学习的见证,如果你有幸看见,不要吐槽,不足之处请指点,相互学习,谢谢!! 请一起共勉!!!!!!!! 使用技术: ...

  9. Python:Day24 类、类的三大特性

    Python有两种编程方式:函数式+面向对象 函数式编程可以做所有的事情,但是否合适? 面向对象: 一.定义 函数: def + 函数名(参数) 面象对象: class  bar--->  名字 ...

  10. 【编辑器】Visual Studio Code

    1.官网:https://code.visualstudio.com/Download 2.插件:https://marketplace.visualstudio.com/VSCode https:/ ...