- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python中的Socket 与 ScoketServer 通信及遇到问题解决方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
Socket有一个缓冲区,缓冲区是一个流,先进先出,发送和取出的可自定义大小的,如果取出的数据未取完缓冲区,则可能存在数据怠慢。其中【recv(1024)】表示从缓冲区里取最大为1024个字节,但实际取值大小是不确定的,推荐其值小于等于8192.
黏包问题:
Socket发送两条连续数据时,可能最终会拼接成一条进行发送 。
解决方法一:
两条数据间进行延时发送,如【tiem.sleep(0.5) #延时0.5s】 。
解决方法二:
每次发送后等待对方确认接收信息数据,发送一条后就立即接收等待 。
解决方法三:
设定接收数据大小,发送端每次发送需要发送的数据的数据大小,接收端通过设置【recv(xx)】只接收确定的大小 。
Socket基本使用
简单的服务器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import
socket
sser
=
socket.socket()
#得到socket对象
sser.bind((
"0.0.0.0"
,
2699
))
#建立监听
sser.listen(
3
)
print
(
"等等客户端连接"
)
conn,addr
=
sser.accept()
#等待连接,会一直处于阻塞,返回连接对象和对方地址
print
(
"有客户端已经连接,IP地址和端口为:"
,addr)
#接收数据,会一直阻塞,建议低于8192
#使用连接对象操作
rdata
=
conn.recv(
1024
)
print
(rdata.decode(
"gbk"
))
conn.send(
"服务器返回,收到数据"
.encode(
"gbk"
))
#发送数据,使用连接对象操作
#关闭连接
sser.close()
|
简单的客户端:
1
2
3
4
5
6
7
8
9
10
11
|
import
socket
sclient
=
socket.socket()
#得到socket对象
#连接服务器
#失败会报错:ConnectionRefusedError
sclient.connect((
"192.168.1.135"
,
2699
))
sclient.send(
"东小东"
.encode(
"gbk"
))
#发送数据
#接收数据,会一直阻塞,建议低于8192
rdata
=
sclient.recv(
1024
)
print
(rdata.decode(
"gbk"
))
#关闭连接
sclient.close()
|
Soket进阶:
服务器进阶:
实现客户循环连接及数据循环收发和判断客户端是否断开 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import
socket
sser
=
socket.socket()
#得到socket对象
sser.bind((
"0.0.0.0"
,
2699
))
#建立监听
sser.listen(
3
)
while
True
:
print
(
"等等客户端连接"
)
conn,addr
=
sser.accept()
#等待连接,会一直处于阻塞,返回连接对象和对方地址
print
(
"有客户端已经连接,IP地址和端口为:"
,addr)
conn.send((
"服务器欢迎你:%s\r\n"
%
(
str
(addr))).encode(
"gbk"
))
# 发送数据,使用连接对象操作
while
True
:
#接收数据,会一直阻塞
#使用连接对象操作
rdata
=
conn.recv(
1024
)
if
not
rdata:
break
#判断客户端是否断开,断开则收到空数据
print
(rdata.decode(
"gbk"
))
conn.send(
"服务器返回,收到数据\r\n"
.encode(
"gbk"
))
#发送数据,使用连接对象操作
#关闭连接
sser.close()
|
客户端进阶:
实现循环收发和判断服务器是否断开 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
socket
sclient
=
socket.socket()
#得到socket对象
#连接服务器
#失败会报错:ConnectionRefusedError
sclient.connect((
"192.168.1.135"
,
2699
))
while
True
:
#接收数据,会一直阻塞
rdata
=
sclient.recv(
1024
)
if
not
rdata:
break
# 判断服务器是否断开,断开则收到空数据
print
(rdata.decode(
"gbk"
))
sclient.send((
"客户端收到数据:%s\r\n"
%
rdata.decode(
"gbk"
)).encode(
"gbk"
))
# 发送数据
#关闭连接
sclient.close()
|
注意:
发送数据不可发送空字符,否则会卡住,解决方法为判断输入的是否为空值,空值则进行数据发送 。
1
2
3
4
|
strx
=
input
(
"输入:"
).strip()
#得到控制台输入值
if
(
len
(strx)
=
=
0
):
continue
#如果为空字符,则跳出本次循环
print
(strx)
#打印
sclient.send(strx.encode(
"gbk"
))
# 发送数据
|
发送大数据:
先发送总体数据大小,socket另一端判断实际接收的数据大小与总数据大小进行比较,循环recv()进行数据接收 。
简单的ssh实现:
服务端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import
os
import
socket
sser
=
socket.socket()
#得到socket对象
sser.bind((
"0.0.0.0"
,
2697
))
#建立监听
sser.listen(
3
)
while
True
:
print
(
"等等客户端连接"
)
conn,addr
=
sser.accept()
#等待连接,会一直处于阻塞,返回连接对象和对方地址
print
(
"有客户端已经连接,IP地址和端口为:"
,addr)
conn.send((
"服务器欢迎你:%s\r\n"
%
(
str
(addr))).encode(
"gbk"
))
# 发送数据,使用连接对象操作
while
True
:
#接收数据,会一直阻塞
rdata
=
conn.recv(
1024
)
if
not
rdata:
break
#判断客户端是否断开,断开则收到空数据
sendtox
=
os.popen(rdata.decode(
"gbk"
)).read()
#执行命令
conn.send(
str
(
len
(sendtox)).encode(
"gbk"
))
#发送执行命令的结果长度
#如果长度大于0 则发送命令结果数据
if
len
(sendtox)>
0
:
if
conn.recv(
10
).decode(
"gbk"
)
=
=
"1"
:
conn.sendall(sendtox.encode(
"gbk"
))
#发送最终数据
#关闭连接
sser.close()
|
客户端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
import
socket
sclient
=
socket.socket()
#得到socket对象
#连接服务器
#失败会报错:ConnectionRefusedError
sclient.connect((
"192.168.43.21"
,
2697
))
# 接收数据,会一直阻塞
rdata
=
sclient.recv(
1024
)
print
(rdata.decode(
"gbk"
))
while
True
:
strx
=
input
(
"请输入命令:"
).strip()
# 得到控制台输入值
if
(
len
(strx)
=
=
0
):
continue
# 如果为空字符,则跳出本次循环
sclient.send(strx.encode(
"gbk"
))
# 发送数据
rdata
=
sclient.recv(
10
)
if
not
rdata:
break
# 判断服务器是否断开,断开则收到空数据
#判断命令是否执行成功,0为失败
dataall
=
int
(rdata.decode(
"gbk"
))
if
dataall
=
=
0
:
continue
sclient.send(
"1"
.encode(
"gbk"
))
# 发送确认接收数据命令
#循环接收数据
datanew
=
0
while
dataall !
=
datanew:
rdata
=
sclient.recv(
1024
).decode(
"gbk"
)
datanew
+
=
len
(rdata)
print
(rdata)
#关闭连接
sclient.close()
|
发送文件:
发送文件,使用read()读取文件数据后,可循环调用send()发送数据,或者使用sendall()一次性发送所有数据,socket另一端接收可循环recv()进行数据接收,且每次接收的数据大小是不确定的。文件传输需要验证发送和接受的数据是否完全一致,可以通过数据大小加md5双重验证,发送端:md5在每次发送一条数据时进行update(),在数据发送完成后再发送md5值;接受端:md5在每次接收到一条数据后进行update(),在文件接收完成后再接收发送端发送的md5值,将两值进行比较,相同则表示传输无丢包,但加入md5校验,将会影响传输速率.
发送文件数据:先发送总体数据大小,socket另一端判断实际接收的数据大小与总数据大小进行比较,循环recv()进行数据接收 。
示例:客户端发送文件名,服务器判断文件是否存在,如果不存在或者是空文件则不进行传输,服务器进行文件发送,客户端实现文件接收 。
服务器 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
import
os
import
socket
sser
=
socket.socket()
#得到socket对象
sser.bind((
"0.0.0.0"
,
2697
))
#建立监听
sser.listen(
3
)
while
True
:
print
(
"等等客户端连接"
)
conn,addr
=
sser.accept()
#等待连接,会一直处于阻塞,返回连接对象和对方地址
print
(
"有客户端已经连接,IP地址和端口为:"
,addr)
conn.send((
"服务器欢迎你:%s\r\n"
%
(
str
(addr))).encode(
"gbk"
))
# 发送数据,使用连接对象操作
while
True
:
#接收数据,会一直阻塞
rdata
=
conn.recv(
1024
)
if
not
rdata:
break
#判断客户端是否断开,断开则收到空数据
filesize
=
0
filenamex
=
rdata.decode(
"gbk"
)
if
os.path.isfile(filenamex):
#判断是否是文件
filesize
=
os.stat(filenamex).st_size
#得到文件大小
conn.send(
str
(filesize).encode(
"gbk"
))
#不是文件则发送0,是文件则是实际大小
#如果文件大小大于0 则发送文件
if
filesize>
0
:
if
conn.recv(
10
).decode(
"gbk"
)
=
=
"1"
:
#等待确认接收命令
#一行一行发送数据
f
=
open
(filenamex,
"rb"
)
for
linex
in
f:
conn.sendall(linex)
#发送最终数据
#关闭连接
sser.close()
|
客户端 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
import
socket
sclient
=
socket.socket()
#得到socket对象
#连接服务器
#失败会报错:ConnectionRefusedError
sclient.connect((
"192.168.43.21"
,
2697
))
# 接收数据,会一直阻塞
rdata
=
sclient.recv(
1024
)
print
(rdata.decode(
"gbk"
))
while
True
:
filenamex
=
input
(
"请输入文件名:"
).strip()
# 得到控制台输入值
if
(
len
(filenamex)
=
=
0
):
continue
# 如果为空字符,则跳出本次循环
sclient.send(filenamex.encode(
"gbk"
))
# 发送数据
rdata
=
sclient.recv(
10
)
if
not
rdata:
break
# 判断服务器是否断开,断开则收到空数据
#判断命令是否执行成功,0为失败
dataall
=
int
(rdata.decode(
"gbk"
))
if
dataall
=
=
0
:
print
(
"文件不存在或者为空"
)
continue
sclient.send(
"1"
.encode(
"gbk"
))
# 发送确认接收数据命令
#打开文件
f
=
open
(filenamex,
"wb"
)
#循环接收数据
datanew
=
0
while
dataall !
=
datanew:
rdata
=
sclient.recv(
1024
)
datanew
+
=
len
(rdata)
f.write(rdata)
print
(
"文件(%s)接收完毕"
%
filenamex)
f.close()
#关闭文件
#关闭连接
sclient.close()
|
ScoketServer 。
服务端实现多并发效果,可以同时接入多个客户端 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import
socketserver
#建立一个类,必须继承 socketserver.BaseRequestHandler 类
class
DongSocket(socketserver.BaseRequestHandler):
#必须重写handle方法
def
handle(
self
):
print
(
"建立新连接,对方地址为:{}"
.
format
(
self
.client_address))
while
True
:
try
:
self
.datax
=
self
.request.recv(
1024
).decode(
"gbk"
)
#接收数据
print
(
"接收的数据为:%s"
%
self
.datax)
self
.request.send((
"服务器返回数据:%s"
%
self
.datax).encode(
"gbk"
))
except
Exception as e:
print
(
"断开,再见:{}"
.
format
(
self
.client_address))
break
#参数:(("ip",端口),自定义类)
#ss=socketserver.TCPServer(("0.0.0.0",2351),DongSocket) #与之前的socket服务器效果一致,同时只能连接一个客户端
ss
=
socketserver.ThreadingTCPServer((
"0.0.0.0"
,
2351
),DongSocket)
#同时可以连接多个客户端,多并发
ss.serve_forever()
|
总结 。
以上所述是小编给大家介绍的Python中的Socket 与 ScoketServer 通信及遇到问题解决方法 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我网站的支持! 。
原文链接:https://www.cnblogs.com/dongxiaodong/p/10495735.html 。
最后此篇关于Python中的Socket 与 ScoketServer 通信及遇到问题解决方法的文章就讲到这里了,如果你想了解更多关于Python中的Socket 与 ScoketServer 通信及遇到问题解决方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
大多数语言都支持双向进程通信。例如,在 Python 中,我可以(草率地)执行以下操作: >>> from subprocess import * >>> p = Popen('nslookup',
致力于使用 C++ 在 arduino 和 PC (Win 7) 之间进行通信。使用 WriteFile 和 ReadFile 创建通信或简单地发送或接收数据没有问题。但是当我想以某种方式“协调”沟通
我们正在开发一个基于微服务的应用程序。它们将使用 Helm Package Manager 部署到 kubernetes,并且它们都存储了自己的存储库和 helm chart。以下是我们微服务的名称。
我正在开发一个大型 MVVM 应用程序。我为此使用了 MVVM 轻量级工具包。该应用程序就像一个带有后退和前进按钮的网络浏览器。主视图是一个用户控件。我在主视图用户控件中放置了后退和前进按钮。主视图又
我在 java 和 freepascal(lazarus) 应用程序之间的通信有问题。我使用套接字。它们正确连接。一切都很顺利,直到我想从一个应用程序向另一个应用程序发送一些东西。在java而不是“a
我已经使用客户端套接字和服务器套接字使用C#编写了群聊。 当我使用VS 2017在自己的PC中运行程序(服务器和客户端)时,客户端和服务器之间的通信工作正常。 当我在笔记本电脑中运行客户端程序,并在自
Kubernetes 中两个不同 Pod 之间的通信是如何发生的? 就我而言,我有两个 Pod:前端和后端,它们都有不同的容器。 我希望我的前端 pod 与后端 pod 通信,但我不想使用后端 pod
我正在尝试在浏览器中嵌入的 flash 实例与在 C# WinForms 应用程序中运行的 flash 实例之间进行通信...我收到一个编译错误,内容为: 1119 Access of possibl
鉴于网络上缺乏信息,请问一个问题:我要在 Android 中创建一个应用程序,使用一个数据库应用程序 rails 。为此,我需要一个手动 session 。所以如果有人准备好了示例/教程显示通信 an
我正在编写一个应用程序,它将通过 MySQL 数据库对用户进行身份验证。我已经用 Java (android) 编写了它,但现在正在移植到 Windows 手机。 PHP 文件使用 $get 然后回显
是否可以通过互联网在两个不同设备上的两个不同应用程序之间建立通信。我想从设备 A 上的应用程序点击一个设备 B 上的应用程序,然后从设备 B 上的应用程序获取数据到设备 A 上的应用程序。如果可能,如
这是脚本: 它被放置在其他网站上。 com 并显示一个 iframe。如果有人点击 iframe 中的某个内容,脚本应该将一个 div 写入 othersite 。 com. 所以我的问题是如何做到
你好我是 php 的新手,我用 c++ 编写了整个代码并想在 php 中使用这段代码。所以我为我的代码制作了 dll 以使用它。但是我不能在 php 中使用这个 dll,可以谁能给我完整的代码来使用
我确定之前已经有人问过(并回答过)此类问题,所以如果是这样,请将我链接到之前的讨论... 在 C++ 中,假设我有一个 ClassA 类型的对象,其中包含一个 ClassB 类型的私有(private
我正在尝试使用 ATmega32 进行串行通信。首先,我使用 RS232,使用 USB-to-RS232 建立使用串行终端的接收和传输(在我的例子中是 tera 术语)。无论我从串行终端 Atmega
我找不到适用于 Ruby 的 SSL 实现。 我的部分项目需要服务器和客户端之间的安全通信链接,我希望为此使用 SSL 以创建安全 session 。 谢谢 最佳答案 如果你使用 Ruby 1.9.x
我正在尝试在客户端/服务器之间进行 SSL 通信。 到目前为止,我已经从 keystore 创建了 java.security.cert.X509Certificate。接下来我应该怎么做才能使这次沟
我在与 Windows 上的 USB 设备 通信时遇到问题。我不能使用 libusb 或 WinUSB,因为我有一个特定的驱动程序(Silabs USB 到 UART,这是一个 USB 到串口的桥接器
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我发现 xcom 实际上是将数据写入数据库并从其他任务中提取数据。我的数据集很大,将其腌制并写入数据库会导致一些不必要的延迟。有没有办法在不使用 xcom 的情况下在同一 Airflow Dag 中的
我是一名优秀的程序员,十分优秀!