Python socket服务常用操作代码实例


Posted in Python onJune 22, 2020

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。

1. 实现客户端发送字符,服务器返回大写的字符:

服务器:

import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):     # 通过类的继承,实现
  def handle(self):          # 重写父类的handle方法,所有的操作都在此方法中
    while True:           # 循环,不停的接收从客户端来的数据
      try:
        self.data = self.request.recv(1024).strip()     # 从客户端接收数据,每次收1024字节
        print("{} send:".format(self.client_address), self.data)
        self.request.send(self.data.upper())         # 从服务器发送给客户端数据
      except ConnectionResetError as e:
        print('Error: ',e)
        break

if __name__ == '__main__':
  host,port = 'localhost',9999
  server = socketserver.ThreadingTCPServer((host,port),MyTCPHandler)   # 通过多线程实现多个客户端连接,每个客户端连接都是一个线程
  server.serve_forever()                        # 一直运行服务

客户端:

import socket

client = socket.socket()         # socket对象
client.connect(('localhost',9999))   # 连接服务器地址和端口

while True:               # 循环,不停的输入发送数据
  con = input('>>>:').strip()
  if len(con) ==0: continue      # 不能发送空数据,否则会阻塞
  client.send(con.encode('utf-8'))  # 发送数据,必须是二进制的
  data = client.recv(1024)      # 接收服务器返回的数据
  print(data.decode())        # 打印 解码后的数据

client.close()           # 关闭

2. 通过socket执行服务器命令:

用法:直接在客户端输入处输入命令如:ipconfig

服务器:

import socket
import os
import threading

def tcplink(sock, addr):
  print('Accept new connection from %s:%s...' % addr)
  while True:     # 和每个接入的客户端,进行多次数据通信
    data = sock.recv(1024) # 接收客户端数据
    if not data or data.decode('utf-8') == 'exit': # 如果客户端不发送数据或者发送了exit
      print('client disconnected.')
      break
    content = os.popen(data.decode('utf-8')).read() # 对发送来的数据执行cmd命令,获取结果
    if len(content) == 0:      #如果执行的命令结果为空的,就手动造一个结果。因为如果为空数据,会挂起,无法正常发送。
      content = 'cmd not exists.'
    sock.send(str(len(content.encode('utf-8'))).encode('utf-8')) # 发送数据的长度
    print('send length:', (len(content.encode('utf-8'))))
    # print('content,', content.encode('utf-8'))
    recv = sock.recv(1024) # 因为上下都有一个send连在一起,可能发生粘包现象,为了防止这种情况,可以让客户端重新应答一下
    print('Answer:',recv.decode('utf-8'))
    sock.send(content.encode('utf-8'))    # 发送数据
    print('send finished.')
  sock.close()
  print('Connection from %s:%s closed.' % addr)


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听端口:
s.bind(('127.0.0.1', 9999))
s.listen(3)
print('Waiting for connection...')

while True:
  # 接受一个新连接:
  sock, addr = s.accept()
  # 创建新线程来处理TCP连接:
  t = threading.Thread(target=tcplink, args=(sock, addr))
  t.start()

客户端:

import socket

# AF_INET 代表ipv4,SOCK_STREAM 代表TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   # 确定网络协议,生成对象
s.connect(('127.0.0.1',9999)) # 连接服务器的地址和端口,元组的形式。
while True:
  msg = input('>>:').strip()
  if len(msg) != 0:         # 如果消息为空,会一直挂起,所以不能为空
    if msg =='exit':
      s.close()           # 关闭连接
      print('Connection closed.')
      break
    s.send(msg.encode('utf-8'))    # 给服务器发送数据,必须是二进制的
    length = s.recv(1024)      # 首先接收服务器返回的将要接收的数据的长度信息。
    s.send(b'Ready to receive...')  # 发送接收命令
    length = int(length.decode('utf-8'))
    print('receive len:', length)
    data_len = 0
    data_recv = b''
    while data_len < length:  # 已经接收的信息的长度,如果小于总长度
      data = s.recv(1024)   # 从服务器接收数据
      data_recv += data
      data_len += len(data)
    print(data_recv.decode('utf-8')) # 打印返回的数据。

3. 通过socket传输文件:

用法:get 文件名

服务器:

import socket
import os
import hashlib
import threading

def tcplink(sock, addr):
  print('Accept new connection from %s:%s...' % addr)
  while True:     # 和每个接入的客户端,进行多次数据通信
    data = sock.recv(1024) # 接收客户端数据
    if not data or data.decode('utf-8') == 'exit': # 如果客户端不发送数据或者发送了exit
      print('client disconnected.')
      break
    oper,filename = data.decode('utf-8').split() # 对接收的数据按照空格分割
    if oper == 'get':
      m = hashlib.md5()
      if os.path.isfile(filename):
        size = os.stat(filename).st_size  # 获取文件大小
        print('Send size:',size)
        sock.send(str(size).encode('utf-8')) # 发送文件大小
        recv = sock.recv(1024)       # 接收客户端确认信息(因为上下文两个send是连着的,所以为了防止粘包,接收一次信息)
        f = open(filename,'rb')
        for line in f:
          sock.send(line)  #读取文件,发送给客户端
          m.update(line)
        # print('Send finished.',m.hexdigest())  # 打印md5的值
        sock.send(m.hexdigest().encode('utf-8')) # 把md5的值发送给客户端
  sock.close()
  print('Connection from %s:%s closed.' % addr)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听端口:
s.bind(('127.0.0.1', 9999))
s.listen(3)
print('Waiting for connection...')

while True:
  # 接受一个新连接:
  sock, addr = s.accept()
  # 创建新线程来处理TCP连接:
  t = threading.Thread(target=tcplink, args=(sock, addr))
  t.start()

客户端:

import socket
import hashlib

# AF_INET 代表ipv4,SOCK_STREAM 代表TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   # 确定网络协议,生成对象
s.connect(('127.0.0.1',9999)) # 连接服务器的地址和端口,元组的形式。
while True:
  msg = input('>>:').strip()
  if len(msg) != 0:         # 如果消息为空,会一直挂起,所以不能为空
    if msg =='exit':
      s.close()           # 关闭连接
      print('Connection closed.')
      break
    s.send(msg.encode('utf-8'))    # 给服务器发送数据,必须是二进制的
    length = s.recv(1024)      # 首先接收服务器返回的将要接收的数据的长度信息。
    s.send(b'Ready to receive...')  # 发送接收确认命令
    length = int(length.decode('utf-8'))
    print('Recv size:', length)
    data_len = 0
    data_recv = b''
    # 新文件名
    fileName = msg.split()[-1].split('.')[0]
    fileExt = msg.split()[-1].split('.')[-1]
    newFile = fileName+'-1.'+fileExt
    f = open(newFile,'wb') # 打开文件,准备写入服务器发过来的文件
    m = hashlib.md5()
    while data_len < length:  # 已经接收的信息的长度,如果小于总长度
      size = length - data_len 
      if size > 1024:   # 如果剩下的信息长度大于1024,即不能一次性发完。
        size = 1024
      else:    # 如果能一次性发完,就只收剩下的信息。目的是准确的接收文件的大小,把可能粘连的send的数据留给下一次recv
        size = length-data_len
      data = s.recv(size)   # 从服务器接收数据
      f.write(data)
      m.update(data)
      data_len += len(data)
    f.close()
    print('recv_md5:',m.hexdigest()) # 打印返回的数据。
    recv = s.recv(1024)   # 接收下一次send的数据,即md5的值。
    print('orig_md5:',recv.decode())

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python自动化测试之从命令行运行测试用例with verbosity
Sep 28 Python
使用Python的Tornado框架实现一个Web端图书展示页面
Jul 11 Python
Python中read()、readline()和readlines()三者间的区别和用法
Jul 30 Python
Python OpenCV处理图像之图像直方图和反向投影
Jul 10 Python
python数据批量写入ScrolledText的优化方法
Oct 11 Python
python通过TimedRotatingFileHandler按时间切割日志
Jul 17 Python
PyQt5使用QTimer实现电子时钟
Jul 29 Python
FFT快速傅里叶变换的python实现过程解析
Oct 21 Python
简单了解python中的f.b.u.r函数
Nov 02 Python
python之array赋值技巧分享
Nov 28 Python
Python基于execjs运行js过程解析
Nov 27 Python
Python 无限级分类树状结构生成算法的实现
Jan 21 Python
Python如何实现后端自定义认证并实现多条件登陆
Jun 22 #Python
零基础小白多久能学会python
Jun 22 #Python
Keras-多输入多输出实例(多任务)
Jun 22 #Python
python和c语言哪个更适合初学者
Jun 22 #Python
Virtualenv 搭建 Py项目运行环境的教程详解
Jun 22 #Python
终于搞懂了Keras中multiloss的对应关系介绍
Jun 22 #Python
keras 多任务多loss实例
Jun 22 #Python
You might like
php接口与接口引用的深入解析
2013/08/09 PHP
PHP获取当前日期和时间及格式化方法参数
2015/05/11 PHP
php分页查询mysql结果的base64处理方法示例
2017/05/18 PHP
php实现JWT(json web token)鉴权实例详解
2019/11/05 PHP
JavaScript语法着色引擎(demo及打包文件下载)
2007/06/13 Javascript
javascript实现在网页任意处点左键弹出隐藏菜单的方法
2015/05/13 Javascript
在javascript中创建对象的各种模式解析
2016/05/16 Javascript
el表达式 写入bootstrap表格数据页面的实例代码
2017/01/11 Javascript
详解AngularJS用Interceptors来统一处理HTTP请求和响应
2017/06/08 Javascript
Vuex 入门教程
2018/01/10 Javascript
Vue.directive()的用法和实例详解
2018/03/04 Javascript
微信小程序文章详情页跳转案例详解
2019/07/09 Javascript
js贪心算法 钱币找零问题代码实例
2019/09/11 Javascript
Antd的table组件表格的序号自增操作
2020/10/27 Javascript
Python的装饰器使用详解
2017/06/26 Python
python实现数据图表
2017/07/29 Python
Python实现的视频播放器功能完整示例
2018/02/01 Python
浅谈python正则的常用方法 覆盖范围70%以上
2018/03/14 Python
使用python语言,比较两个字符串是否相同的实例
2018/06/29 Python
Python实现对文件进行单词划分并去重排序操作示例
2018/07/10 Python
在Pandas中给多层索引降级的方法
2018/11/16 Python
Python3 导入上级目录中的模块实例
2019/02/16 Python
pywinauto自动化操作记事本
2019/08/26 Python
wxPython绘图模块wxPyPlot实现数据可视化
2019/11/19 Python
python单例设计模式实现解析
2020/01/07 Python
解决python虚拟环境切换无效的问题
2020/04/30 Python
Web页面中八种创建多列等高(等高列布局)的实现技术
2012/12/24 HTML / CSS
日本整理专家Marie Kondo的官方在线商店:KonMari
2020/06/29 全球购物
浙大网新C/C++面试解惑
2015/05/27 面试题
这76道Java面试题及答案,祝你能成功通过面试
2016/04/16 面试题
计算机专业职业规划
2014/02/28 职场文书
教师三严三实对照检查材料
2014/09/25 职场文书
《用字母表示数》教学反思
2016/02/17 职场文书
python实现的web监控系统
2021/04/27 Python
悬疑名作《朋友游戏》动画无字ED宣传片 新角色公开
2022/04/13 日漫
js判断两个数组相等的5种方法
2022/05/06 Javascript