一、前言

  上一篇中我们已经知道了客户端通过socket来连接服务端,进行了一次数据传输,那如何实现客户端多次发生数据?而服务端接受多个客户端呢?

二、发送中文信息

  在python3中,socket只能发送bytes类型的数据,bytes类型只能表示0-225的ASCII码的值,并不能表示中文,所以当我们需要发送中文时,需要使用到编码和解码。

客户端:

import socket
# 客户端 # 声明协议类型,同时生成socket对象
client = socket.socket() #
client.connect(('localhost', 8888)) # python3 接收字节流数据
msg = input('>>:').strip()
client.send(msg.encode('utf-8')) # 先编码成utf-8格式
data = client.recv(1024) # 1024字节的数据
print(data)
print(data.decode())

服务端:

import socket

# 声明协议类型

server = socket.socket()

# 绑定本地网卡(多网卡选择),端口
server.bind(('localhost', 8888)) # 监听端口
server.listen() # 监听 # conn 就是客户端连接后,在服务器端为其生成的一个连接实例
# address 是客户端的 hostaddr,port conn, address = server.accept()
print("进入等待时间....")
# 等待
# print(conn, address)
print("收到连接....") # 接收数据
data_server = conn.recv(1024) print('receive:', data_server.decode()) # 解码
# 返回一个值
conn.send(data_server)

三、Socket实现多个连接

  这个事例需要在Linux环境下测试,在windows中测试时,多个客户端同时连接(也就是同时运行多个socket_client.py程序),其中一个断开,服务端会报错。Linux环境python版本为3.5。

  事例代码:

客户端:

import socket
# 客户端 # 声明协议类型,同时生成socket对象
client = socket.socket() #
client.connect(('localhost', 8888)) # python3 接收字节流数据
while True:
msg = input('>>:').strip()
if len(msg) == 0: # 输入不能为空
continue
client.send(msg.encode('utf-8'))
data = client.recv(1024) # 1024字节的数据
print(data)
print(data.decode())

  事例中输入为空(即len(msg==0))是不可以的,如果不输入任何东西,socket程序默认等待你的输入,所以程序会卡掉。

服务端:

# -*- coding: UTF-8 -*-

import socket

# 声明协议类型

server = socket.socket()

# 绑定本地网卡(多网卡选择),端口
server.bind(('localhost', 8888)) # 监听端口
server.listen(5) # 监听 while True:
conn, address = server.accept()
print("进入等待时间....")
while True:
print("收到连接....")
# 接收数据
data_server = conn.recv(1024)
if not data_server: # 这里判断客户端断开的情况,不控制会无限循环
print('client is lost...')
break
print('receive:', data_server.decode())
# 返回一个值
conn.send(data_server)

  在Linux服务器上,我开启了6个客户端,每个客户端输入一次就断开(即显示了client has lost...),服务端分别和六个客户端连接并接收数据。

四、实现ssh功能

4.1 测试环境

  服务端: 172.16.200.49,监听端口('0.0.0.0', 8888),Linux系统

  客户端:本机win10

4.2 测试代码

  服务端:

# -*- coding: UTF-8 -*-

import socket
import os # 声明协议类型 server = socket.socket() # 绑定本地网卡(多网卡选择),端口
server.bind(('0.0.0.0', 8888)) # 监听端口
server.listen() # 监听 while True:
conn, address = server.accept()
print("进入等待时间....")
while True:
print("收到连接....")
# 接收数据
data_server = conn.recv(1024)
if not data_server:
print('client is lost...')
break
res = os.popen("{}".format(data_server.decode())).read() # 将执行命令的结果存储返回
# 返回结果
conn.send(res.encode('utf-8'))

  客户端:

# -*- coding: UTF-8 -*-

import socket
# 客户端 # 声明协议类型,同时生成socket对象
client = socket.socket() #
client.connect(('172.16.200.49', 8888)) # 服务端ip和端口 # python3 接收字节流数据
while True:
msg = input('>>:').strip()
if len(msg) == 0:
continue
client.send(msg.encode('utf-8'))
data = client.recv(1024) # 1024字节的数据
print(data.decode())

  结果如下:

  

  

  注:socket中recv()和send()函数接收和发送数据大小都是有限制的。如果一次发送太大,客户端接收不完,就会先存储在缓存当中。但是下一次命令,客户端接收的还是上次命令没有发完的数据。

四、模拟FTP上传文件

  本例当服务端在Linux环境中,struck模块有些问题....,目前在win10中可以正常运行

  服务端: 

# -*- coding: UTF-8 -*-
import struct
import socket class FtpServer(object): def __init__(self, host, port):
self.host = host
self.port = port def ftp_server(self):
# 声明协议类型
ftp_server = socket.socket() # 绑定本地网卡(多网卡选择),端口
ftp_server.bind((self.host, self.port)) # 监听端口
ftp_server.listen() # 监听
while True:
print('等待...')
conn, address = ftp_server.accept() while True: file_info = struct.calcsize('128sl') buf = conn.recv(file_info) if buf:
file_name, file_size = struct.unpack('128sl', buf)
# 使用strip()删除打包时附加的多余空字符
file_new_name = file_name.decode().strip('\00')
print('start receiving...')
fw = open(file_new_name, 'wb')
received_size = 0 # 接收文件的大小
while not received_size == file_size:
if file_size - received_size > 1024:
r_data = conn.recv(1024)
received_size += len(r_data)
else:
r_data = conn.recv(file_size - received_size)
received_size = file_size fw.write(r_data)
fw.close() if __name__ == '__main__':
server = FtpServer('localhost', 8888)
server.ftp_server()

  客户端:

# -*- coding: UTF-8 -*-
import socket
import os
import struct class FtpClient(object):
# 定义一个FtpClien类 def __init__(self, host, port):
self.host = host
self.port = port def client_push(self): # 声明协议类型,同时生成socket对象
ftp_client = socket.socket() # 连接服务端
ftp_client.connect((self.host, self.port)) while True:
# 切换文件目录路径
print("输入文件目录路径")
pwd = input(">>:").strip() # 列出文件名称
files_list = os.listdir('{}'.format(pwd))
for i in files_list:
print(i) file_name = input('输入上传的文件名:').strip()
file_path = os.path.join(pwd, file_name)
if os.path.isfile(file_path):
file_info = struct.calcsize('128sl') # 定义打包规则
f_head = struct.pack('128sl', file_name.encode('utf-8'), os.stat(file_path).st_size)
ftp_client.send(f_head)
fo = open(file_path, 'rb')
while True:
file_data = fo.read(1024)
if not file_data:
break
ftp_client.send(file_data)
fo.close()
# 上传文件
ftp_client.send(file_data) # client.close()
if __name__ == '__main__':
client = FtpClient('localhost', 8888)
client.client_push()

  结果:

  

  在socket_server.py文件位置处能看到上传的文件

  

通过socket实现多个连接并实现ssh功能的更多相关文章

  1. python通过socket实现多个连接并实现ssh功能详解

    python通过socket实现多个连接并实现ssh功能详解 一.前言 上一篇中我们已经知道了客户端通过socket来连接服务端,进行了一次数据传输,那如何实现客户端多次发生数据?而服务端接受多个客户 ...

  2. ZeroMQ接口函数之 :zmq_connect - 由一个socket创建一个对外连接

    ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_connect zmq_connect(3)  ØMQ Manual - ØMQ/3.2.5 Name zmq_c ...

  3. PHP Socket(套接字连接)扩展简介和使用方法

    PHP socket扩展是基于流行的BSD sockets,实现了和socket通讯功能的底层接口,它可以和客户端一样当做一个socket服务器. 使用这些函数时请注意,虽然他们中有很多和C函数同名的 ...

  4. com.microsoft.sqlserver.jdbc.SQLServerException: Socket closed 或者 该连接已关闭

    com.microsoft.sqlserver.jdbc.SQLServerException: Socket closed 或者 该连接已关闭 解决方案: DBUtil公共方法如下: package ...

  5. nodejs socket server 强制关闭客户端连接

    nodejs socket server 强制关闭客户端连接: client.destroy()

  6. python socket实现多个连接

    socket实现多个连接 前戏很重要~~ 在实现多个连接之前,先实现下多次发送和接收数据. 如果要多次接收数据,那么在服务器端的接收和客户端的发送部分就必须使用循环. 以下代码在python3.5下运 ...

  7. 关于Socket的建立及连接

    最近在做一个东西,目前考虑的是采用Socket连接,从网上找了一个SuperSocket的socket通信框架.... 关于Socket连接,个人并不是搞得太懂,写的东西也全是个人理解,那么这里先整理 ...

  8. 运用socket实现简单的ssh功能

    在python socket知识点中已经对socket进行了初步的了解,那现在就使用这些知识来实现一个简单的ssh(Secure Shell)功能. 首先同样是建立两个端(服务器端和客户端) 需求是: ...

  9. Navicat for MySQL用ssh功能连接远程数据库

    转载自:http://holy2010.blog.51cto.com/1086044/518431 实现用本地的ssh隧道起到加密功能 在windows平台上运行Navicat for MySQL(h ...

随机推荐

  1. 论文笔记:Visualizing and Understanding Convolutional Networks

    2014 ECCV 纽约大学 Matthew D. Zeiler, Rob Fergus 简单介绍(What) 提出了一种可视化的技巧,能够看到CNN中间层的特征功能和分类操作. 通过对这些可视化信息 ...

  2. mysql系列学习

    # 帮助help create user;# 查看当前用户select user();# 创建用户create user 'egon'@'localhost' identified by '123'; ...

  3. CSS3 使用 calc() 计算高度 vh px

    Viewport    viewport:可视窗口,也就是浏览器.    vw Viewport宽度, 1vw 等于viewport宽度的1%    vh Viewport高度, 1vh 等于view ...

  4. PSP Daily软件Alpha版本——基于spec评论

    题目要求:每个小组评论其他小组Alpha发布作品的软件功能说明书.要求和提交在[https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/122 ...

  5. Linux发行版本应用场景

    如果你是一个Linux爱好者,想选择一个桌面系统,并且既不想用盗版,又不想花太多钱购买商业系统软件,那么可以选择Ubuntu桌面系统.如果你需要服务器端的Linux系统,想用一个比较稳定的服务器系统, ...

  6. c# 加载图片 正在被占用问题

    问题情境:图片文件加载到pdf中,程序没有退出,再次加载该图片文件,提示被占用. 解决办法: 1.加载文件会锁定该文件,fromfile方法会导致占用内存较大,不使用该方法. FileStream f ...

  7. python 为什么没有自增自减符

    >>> b = 5 >>> a = 5 >>> id(a) 162334512 >>> id(b) 162334512 > ...

  8. c# 画一个报告

    填充控件的grafics属性: private void printReportPage(object sender, System.Drawing.Printing.PrintPageEventAr ...

  9. python 中如何计算时间差...

    Q:如何方便的计算两个时间的差,如两个时间相差几天,几小时等 A:使用datetime模块可以很方便的解决这个问题,举例如下: >>> import datetime>> ...

  10. php中ob缓存机制

    1.ob缓存运行方式 2.注意:在程序中如果开启ob_start(),所有的echo输出都会保存到ob缓存中,可以使用ob系列函数进行操作,如果没有,默认情况下,在程序执行结束,会把缓存中的数据发送给 ...