基于python的客户端与服务器端之间的通信

目录

1.centos配置python3环境

        1.1教程:

        1.2问题解决:

                1.2.1bash: /usr/bin/yum: 没有那个文件或目录

                1.2.2安装python3的依赖包时报错如下

                1.2.3安装5.2.2中的新链接内容执行解压tar包时出现

                1.2.4Linux 正在尝试其他镜像

2.使用Python在两个虚拟机之间建立套接字连接

        2.1TCP

                2.1.1基于TCP的通信

                        2.1.1.1描述:

                        2.1.1.2运行步骤:

                        2.1.1.3截图:

                2.1.2客户端

                        from socket import *

                2.1.3服务器端

                        from socket import *

                2.1.4问题:

                        2.1.4.1虚拟机服务无法访问——No route to host 问题

                        2.1.4.2bind() error : Cannot assign requested address:

                        2.1.4.3SyntaxError: Non-ASCII character '\xe5' in file tcp_client.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

                        2.1.4.4Address already in use

                        2.1.4.5网络服务器只向客户端发送一次数据,而不是循环发送

                        2.1.4.6 broken pipe

        2.2UDP

                2.2.2运行步骤:

                2.2.3截图:

                2.2.2客户端

                        from socket import *

                2.2.3服务器端

                        from socket import *

        2.3UDP和TCP的区别

                1.TCP 面向连接,提供可靠的服务;UDP 是无连接的,即发送数据之前不需要建立连接,UDP 尽最大努力交付,即不保证可靠交付。

                2.具体编程时的区别:

                3. 相比较而言,从代码量及逻辑结构看,UDP程序结构较简单

        2.4源码截图:

                tcp:客户端

                tcp:服务器端

                udp:客户端

                udp:服务器端

1.centos配置python3环境

1.1教程:

centos7 安装python3 环境 https://zhuanlan.zhihu.com/p/492815893

1.2问题解决:

1.2.1bash: /usr/bin/yum: 没有那个文件或目录

参照链接内容:-bash: yum: 未找到命令/-bash: yum: command not found(https://blog.tag.gg/showinfo-3-36222-0.html)

1.2.2安装python3的依赖包时报错如下

```

没有可用软件包 bzip2-devel。

没有可用软件包 ncurses-devel。

没有可用软件包 sqlite-devel。

没有可用软件包 readline-devel。

没有可用软件包 tk-devel。

没有可用软件包 gdbm-devel。

没有可用软件包 libpcap-devel。

没有可用软件包 xz-devel。

```

就直接换了一个教程:CentOS安装Python3

(https://blog.csdn.net/weixin_46048542/article/details/127114019)

需要注意:当我们需要使用不同的python版本的时候,就可以通过命令行输入python2或者python3来开启相应的版本,如下图:

```

[lws@localhost local]$ python3

Python 3.6.2 (default, Jul 29 2018, 09:24:24)

[GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux

Type "help", "copyright", "credits" or "license" for more information.

>>>

```

```

[lws@localhost local]$ python2

Python 2.6.6 (r266:84292, Jan 22 2014, 09:37:14)

[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>>

```

1.2.3安装5.2.2中的新链接内容执行解压tar包时出现

```

tar: 归档文件中异常的 EOF

tar: 归档文件中异常的 EOF

tar:Error is nor recoverable:exiting now"

```

原因:下载的源码包在下载过程中被破坏或者不完整所致。

解决:需要重新下载压缩包。

执行过程:重新执行了两次`wget https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tar.xz`命令,但每次解压tar包都会有这个问题,最后发现是因为第一次下载的不完整压缩包,解压后的文件夹保留,导致后续重新下载的重名文件名带(1)(2)...,系统解压依旧用第一个。只需用`rm -rf 目录名`(f:每次删除前不需要询问)依次删去不完整的即可。

1.2.4Linux 正在尝试其他镜像

很有可能没有联网

可以ping下公用网检查是否联网

若未联网,参看:linux connect: 网络不可达、没有ip解决方法

https://blog.csdn.net/weixin_45142497/article/details/127802896

2.使用Python在两个虚拟机之间建立套接字连接

2.1TCP

2.1.1基于TCP的通信

2.1.1.1描述:

在客户端接受键盘的数据,通过tcp发送到服务器,服务器显示客户端发送的数据,返回`接收到数据的时间+发送过来的数据`。客户端将服务器返回的数据打印在显示屏上。然后重复前面步骤,循环往返,知道客户打输入"exit",套接字关闭。

2.1.1.2运行步骤:

先启动服务端的tcp_server.py,后运行客户端的tcp_client.py

2.1.1.3截图:

客户端:

服务器端:

2.1.2客户端

```

#允许访问server的8000端口 防止数据包被iptables防火墙拦截

#iptables -A IN_public_allow -p tcp --dport 8000 -m state --state NEW -j ACCEPT

from socket import *

tcp_socket=socket(AF_INET,SOCK_STREAM)

server_ip="192.168.149.136"

server_port=8000

tcp_socket.connect((server_ip,server_port))

while(1):

send_data=input("Please input:")

tcp_socket.send(send_data.encode("gbk"))

if send_data=="exit":

break

from_server_msg=tcp_socket.recv(1024)

print(from_server_msg.decode("gbk"))

tcp_socket.close()

```

2.1.3服务器端

```

#服务器端将返回大写数据 改为 服务器接收到数据的时间+“ server has been received”

from socket import *

import time

tcp_server=socket(AF_INET,SOCK_STREAM)

address=("192.168.149.136",8000)

#tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

tcp_server.bind(address)

tcp_server.listen(132)

client_socket,clientAddr=tcp_server.accept()

while 1:

from_client_msg=client_socket.recv(1024)

if (from_client_msg=="exit"):

break

print("receive:",from_client_msg.decode("gbk"))

now_time=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))#用格式化的方式添加服务器端接收到数据的时间

send_data = client_socket.send((str(now_time)+" server has been received").encode(),MSG_NOSIGNAL)

tcp_server.close()

```

2.1.4问题:

2.1.4.1虚拟机服务无法访问——No route to host 问题

问题分析:

- 从client可以ping通server

- 从主机可以ssh登陆到client和server

- 从主机和client访问server的8000端口,得到No route to host

解决方法:

```

方法一: 在 server上执行

 iptables -A IN_public_allow -p tcp --dport 5000 -m state --state NEW -j ACCEPT

具体原因可以参看https://zhuanlan.zhihu.com/p/257083919?utm_id=0

方法二:清理server中的防火墙

使用命令   sudo iptables -F

方法三:server上使用如下命令

sudo firewall-cmd --zone=public --permanent --add-port=5000/tcp

具体参看使用Python在两个虚拟机之间建立TCP套接字连接https://www.5axxw.com/questions/content/k6l9e1?a

```

2.1.4.2bind() error : Cannot assign requested address:

报错原因:服务器的套接字绑定的ip地址是客户端的ip

解决:将服务器,客户端的套接字绑定的ip地址均换为服务器的ip

报错截图:下图是第一张是服务器的tcp编程 第二张是客户端的tcp编程 服务器绑定的ip是客户端的 所以出现了这个问题

参考教程:bind() error : Cannot assign requested address:https://stackoverflow.com/questions/14242549/bind-error-cannot-assign-requested-address)

2.1.4.3SyntaxError: Non-ASCII character '\xe5' in file tcp_client.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

问题分析:上述报错是由于编码格式不匹配导致程序不能识别程序中的中文导致的。

Python2默认的编码格式是ASCII,Python3默认的编码格式是UTF·8。因此,如果我们使用python2运行的巧楠on程序中出现了中文,就需要指定编码格式为UTF-8(如栗使的走Python3不需要指定)

解决:直接使用命令python3 +文件名(如:python3  tcp_client.py)

2.1.4.4Address already in use

问题描述:当我在客户端用ctrl+z(或者是ctrl+c,区别是前者是将任务中断,挂起;后者是强制中断程序执行)中断tcp连接后,再次尝试重启服务器,服务器端出现Address already in use错误

问题分析: bind 普遍遭遇的问题是试图绑定一个已经在使用的端口。该陷阱是也许没有活动的套接字存在,但仍然禁止绑定端口(bind 返回  EADDRINUSE),它由 TCP 套接字状态 TIME_WAIT 引起。该状态在套接字关闭后约保留 2 到 4 分钟。在 TIME_WAIT 状态退出之后,套接字被删除,该地址才能被重新绑定而不出问题。

等待 TIME_WAIT  结束可能是令人恼火的一件事,有方法可以避开  TIME_WAIT 状态。可以给套接字应用 SO_REUSEADDR 套接字选项,以便端口可以马上重用(设置套接字选项避免地址使用错误)。

解决:

方法一:

```

#在服务器bind()前一行加上下面语句tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

```

参考教程:地址已经被使用 - Address already in use

https://www.cnblogs.com/alantu2018/p/8462500.html(我是用python写的,如果是用c写的,可以参看该文章)

方法二:参照——Python:绑定套接字:“地址已经在使用”https://www.dovov.com/python-292.html

方法三:手动杀死进程,这种方法比较麻烦,每次重启服务器 都需要操作

利用`ps -fA | grep python`命令查找正在运行的python进程, 通过向服务器发送信号来停止服务器,杀死对应的进程:

```py

$ ps -fA | grep python

  501 81651 12648   0  9:53PM ttys000    0:00.16 python -m SimpleHTTPServer#第二个是进程号

```

```

kill 81651

```

如果进程没有响应,可能不得不采用更严格的方法,例如发送`SIGKILL`(`kill -s KILL <pid>`或`kill -9 <pid>`) 信号。如下图:

参照教程:[socket.error: [Errno 48\] 地址已被使用

https://stackoverflow.com/questions/19071512/socket-error-errno-48-address-already-in-use

6.1.4.5网络服务器只向客户端发送一次数据,而不是循环发送

客户端截图:

 

服务器端截图:

问题描述:我希望服务器不断地向客户机发送数据流,但是由于某种原因,在接收到第一条数据之后,我的客户机就不再接收/打印任何数据了。

问题分析:server端就能连接一次,s.accept()是阻塞式方式,当得到一个连接后就往后运行,不能再接收客户端连接了。要向每个客户机发送多条消息,需要在`accept()`发生之后进行循环。

解决:将accept放在while外可以实现连续通信。关于为什么要把accept()放到while外面的原因 我也不太清楚

参考:socket 基于tcp的聊天程序中为什么客户端和服务器端都只能收发一次数据https://bbs.csdn.net/topics/100061084(在讨论区中还有另外一种解决方法——创建新线程,但我还是没有看懂)

2.1.4.6 broken pipe

报错截图:

原因:

原因一、项目中存在大量的print输出,导致pipe容量不足,使用nohup后台进程处理之后信息会不断地发送给远程pc,如果信息接着不断发送,就会导致pipe容量不足,信息堵塞。

原因二、tcp/ip连接方式进行数据发送、接收。发送方(客户端)和接收方(服务端),首先建立socket连接,建立连接后进行数据发送接收。连接的两端必须都打开,当连接读端(接收端)关闭,写端(发送端)不能写时会发出SIGPIPE信号,即会生成BROKEN PIPE错误。

比如说:client端用户杀死进程,接口的TCP请求尚未完成(未完成的原因是处理时间长)。 但由于已经杀死了进程,并不会对用户产生任何影响。

这篇文章对于原因分析比较透彻:[tcp连接时,BROKEN PIPE错误的原因以及解决方法](https://www.cnblogs.com/cthon/p/9139553.html)

解决方法:

 一、对于第一种原因,则将项目中所有的print注释或者删除,将必须输出的数据进行日志打印或者输出到指定文件中。

二、对于第二种原因,最好的方式是开发时确保连接两端保持打开或者同时关闭。还可以项目中进行设置,忽略SIGPIPE信号。在python中又两种方式可以实现

```python

方法一:捕获异常

import sys, errno

try:

     IO operation

except IOError as e:

    if e.errno == errno.EPIPE:

         Handle error

方法二:忽略信号

 import signal

signal.signal(signal.SIGPIPE, signal.STG_IIGN)  # 忽略SIGPIPE信号

其他方法参照:Python 的 Broken Pipe 错误问题分析https://blog.csdn.net/qq_31801955/article/details/116738963

```

参考:踩坑日记——tcp/ip,BROKEN PIPE错误的原因以及解决方法:https://blog.csdn.net/qq_56623503/article/details/118676272

结果:对于上述方法均已尝试,并没有对我的程序起作用

2.2UDP

2.2.1基于UDP的通信

2.2.1.1描述:

在客户端接受键盘的数据,通过udp发送到服务器,服务器显示客户端发送的数据,返回`接收到数据的时间+发送过来的数据`。客户端将服务器返回的数据打印在显示屏上。然后重复前面步骤,循环往返,知道客户打输入"exit",套接字关闭。

2.2.1.2运行步骤:

先启动服务端的tcp_server.py,后运行客户端的tcp_client.py

2.2.1.3截图:

客户端:

服务器端:

2.2.2客户端

```

from socket import *

udp_socket=socket(AF_INET,SOCK_DGRAM)

server_ip="192.168.149.136"

server_port=8000

while 1:

send_data=input("Please input:")

udp_socket.sendto(send_data.encode("gbk"),(server_ip,server_port))

if send_data=="exit":

break

server_message,serverAdd=udp_socket.recvfrom(1024)

print(server_message.decode("gbk"))

udp_socket.close()

```

2.2.3服务器端

```

#服务器端将返回大写数据 改为 服务器接收到数据的时间+“ server has been received”

from socket import *

import time

udp_server=socket(AF_INET,SOCK_DGRAM)

address=("192.168.149.136",8000)

udp_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)

udp_server.bind(address)

while 1:

message,clientAdd=udp_server.recvfrom(1024)

print("receive:",message.decode("gbk"))

if message=="exit":

break

now_time=time.strftime('%Y-%m-%d%H:%M:%S',time.localtime(time.time()))#用格式化的方式添加服务器端接收到数据的时间

udp_server.sendto((str(now_time)+" server has been received").encode("gbk"),clientAdd)

udp_server.close()

```

2.3UDP和TCP的区别

1.TCP 面向连接,提供可靠的服务;UDP 是无连接的,即发送数据之前不需要建立连接,UDP 尽最大努力交付,即不保证可靠交付。

tcp协议下,客户端需要先建立对服务器的连接后才能发送数据

udp协议下,客户端不需要事先建立对服务器的连接,它能够直接向服务器端发送数据

2.具体编程时的区别:

两者socket()的参数不同

UDP Server不需要调用listen和accept

UDP收发数据用sendto/recvfrom函数 ,且每次均需指定地址信息

TCP的地址信息在connect/accept时确定

  1. 相比较而言,从代码量及逻辑结构看,UDP程序结构较简单 

2.4源码截图:

tcp:客户端

tcp:服务器端

udp:客户端

udp:服务器端

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python可以使用内置的ftplib模块来实现FTP客户端的设计和实现。 首先,我们需要导入ftplib模块: ```python import ftplib ``` 接下来,我们需要连接到FTP服务器。我们可以使用ftplib.FTP类的connect方法来建立连接: ```python ftp = ftplib.FTP() ftp.connect("ftp服务器地址", "ftp服务器端口") ``` 连接成功后,我们需要登录到FTP服务器。我们可以使用ftplib.FTP类的login方法来登录: ```python ftp.login("用户名", "密码") ``` 登录成功后,我们可以执行各种FTP操作。例如,我们可以列出FTP服务器上的文件列表: ```python files = ftp.nlst() for file in files: print(file) ``` 我们还可以下载文件: ```python ftp.retrbinary("RETR 文件名", open("本地保存路径", "wb").write) ``` 同时,我们还可以上传文件: ```python ftp.storbinary("STOR 文件名", open("本地文件路径", "rb")) ``` 最后,我们可以关闭与FTP服务器的连接: ```python ftp.quit() ``` 通过以上步骤,我们可以实现一个简单的FTP客户端。当然,我们还可以根据具体需求来进一步增加其他功能,例如创建文件夹、删除文件、重命名文件等操作。 需要注意的是,FTP服务器的地址、端口、用户名和密码等参数都需要根据实际情况进行设置,并且在处理错误和异常时需要进行适当的处理。 ### 回答2: Python可以使用ftplib库来实现FTP客户端的设计与实现。以下是一个基本的示例代码: ```python # 导入ftplib库 from ftplib import FTP # 创建FTP客户端对象 ftp = FTP() # 连接FTP服务器 ftp.connect('ftp.example.com', 21) # 登录FTP服务器 ftp.login('username', 'password') # 切换到指定目录 ftp.cwd('path/to/directory') # 列出当前目录下的文件和文件夹 file_list = ftp.nlst() for file in file_list: print(file) # 下载文件 ftp.retrbinary('RETR filename', open('local_filename', 'wb').write) # 上传文件 file = open('local_filename', 'rb') ftp.storbinary('STOR remote_filename', file) # 删除文件 ftp.delete('filename') # 关闭FTP连接 ftp.quit() ``` 以上代码演示了连接到FTP服务器、登录、切换目录、列出文件、下载、上传和删除文件的基本操作。你可以根据具体需求来进行修改和拓展。使用Python实现FTP客户端可以方便地与FTP服务器进行交互,并进行文件传输和管理操作。 ### 回答3: Python实现FTP客户端可以通过使用Python的内置模块`ftplib`来完成。`ftplib`模块提供了一些方法和函数来方便地连接FTP服务器、上传和下载文件。 首先,我们需要通过`ftplib.FTP`类来建立与FTP服务器的连接。我们可以使用`ftplib.FTP`类的`connect(host, port)`方法来指定FTP服务器的地址和端口。例如,我们可以使用以下代码连接到FTP服务器: ```python import ftplib ftp = ftplib.FTP() ftp.connect('ftp.example.com', 21) ``` 接下来,我们需要使用`login(user, passwd)`方法进行登录。我们需要提供用户名和密码。例如,我们可以使用以下代码登录FTP服务器: ```python ftp.login('username', 'password') ``` 登录成功后,我们可以使用`ftp.cwd(directory)`方法切换到目标目录。例如,我们可以使用以下代码进入目标目录: ```python ftp.cwd('directory') ``` 此时,我们可以使用`ftp.retrbinary(command, callback)`方法来下载文件。`retrbinary`方法需要提供FTP服务器的命令和一个回调函数来接收文件数据。例如,我们可以使用以下代码下载文件到本地: ```python def receive_data(data): # 处理接收到的数据,例如将数据写入本地文件 pass ftp.retrbinary('RETR filename', receive_data) ``` 类似地,我们可以使用`ftp.storbinary(command, file)`方法来上传文件。`storbinary`方法需要提供FTP服务器的命令和一个本地文件对象。例如,我们可以使用以下代码将本地文件上传到FTP服务器: ```python file = open('localfile', 'rb') ftp.storbinary('STOR remotefilename', file) file.close() ``` 最后,我们可以使用`ftp.quit()`方法来结束与FTP服务器的连接: ```python ftp.quit() ``` 综上所述,以上是使用Python实现FTP客户端的主要步骤和方法。通过使用`ftplib`模块的相关函数和方法,我们可以方便地连接FTP服务器、登录、切换目录、上传和下载文件等操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值