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 del()函数用法
Mar 24 Python
在Django中创建URLconf相关的通用视图的方法
Jul 20 Python
深入学习python的yield和generator
Mar 10 Python
python利用MethodType绑定方法到类示例代码
Aug 27 Python
Window10+Python3.5安装opencv的教程推荐
Apr 02 Python
Python实现的求解最小公倍数算法示例
May 03 Python
Python 普通最小二乘法(OLS)进行多项式拟合的方法
Dec 29 Python
Python实现代码统计工具
Sep 19 Python
Python 继承,重写,super()调用父类方法操作示例
Sep 29 Python
Django框架模板用法入门教程
Nov 04 Python
python如何编写win程序
Jun 08 Python
python中pathlib模块的基本用法与总结
Aug 17 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
用javascript实现的激活输入框后隐藏初始内容
2007/06/29 Javascript
原生js做的手风琴效果的导航菜单
2013/11/08 Javascript
nodejs批量修改文件编码格式
2015/01/22 NodeJs
jQuery mobile转换url地址及获取url中目录部分的方法
2015/12/04 Javascript
浅谈bootstrap源码分析之tab(选项卡)
2016/06/06 Javascript
Bootstrap基本插件学习笔记之标签切换(17)
2016/12/08 Javascript
js记录点击某个按钮的次数-刷新次数为初始状态的实例
2017/02/15 Javascript
通过一个简单的例子学会vuex与模块化
2017/11/22 Javascript
nodejs操作mongodb的填删改查模块的制作及引入实例
2018/01/02 NodeJs
详解vue使用vue-layer-mobile组件实现toast,loading效果
2018/08/31 Javascript
解决vue单页面应用中动态修改title问题
2019/06/09 Javascript
微信小程序返回上一级页面的实现代码
2020/06/19 Javascript
[03:17]DOTA2-DPC中国联赛1月29日Recap集锦
2021/03/11 DOTA
在Python中操作时间之mktime()方法的使用教程
2015/05/22 Python
Python基于回溯法解决01背包问题实例
2017/12/06 Python
flask使用session保存登录状态及拦截未登录请求代码
2018/01/19 Python
python pandas 对时间序列文件处理的实例
2018/06/22 Python
CSS3教程(6):创建网站多列
2009/04/02 HTML / CSS
CSS3五个技巧给你的网站带来出色的效果
2009/04/02 HTML / CSS
HTML5中通过li-canvas轻松实现单图、多图、圆角图绘制,单行文字、多行文字等
2018/11/30 HTML / CSS
Canvas多边形绘制的实现方法
2019/08/05 HTML / CSS
Born鞋子官网:Born Shoes
2017/04/06 全球购物
火山咖啡:Volcanica Coffee
2019/10/29 全球购物
请问如下代码执行后a和b的值分别是什么
2016/05/05 面试题
出生医学证明样本
2014/01/17 职场文书
社会调查研究计划书
2014/05/01 职场文书
项目委托协议书(最新)
2014/09/13 职场文书
2014年路政工作总结
2014/12/10 职场文书
教师工作表现评语
2014/12/31 职场文书
2015年度党员个人总结
2015/02/14 职场文书
2015年银行个人工作总结
2015/05/14 职场文书
心理健康教育培训研修感言
2015/11/18 职场文书
《狼牙山五壮士》教学反思
2016/02/17 职场文书
《童年》读后感(三篇)
2019/08/27 职场文书
Python Django搭建文件下载服务器的实现
2021/05/10 Python
React 高阶组件HOC用法归纳
2021/06/13 Javascript