目录
1.2.1bash: /usr/bin/yum: 没有那个文件或目录
1.2.3安装5.2.2中的新链接内容执行解压tar包时出现
2.1.4.1虚拟机服务无法访问——No route to host 问题
2.1.4.2bind() error : Cannot assign requested address:
2.1.4.5网络服务器只向客户端发送一次数据,而不是循环发送
1.TCP 面向连接,提供可靠的服务;UDP 是无连接的,即发送数据之前不需要建立连接,UDP 尽最大努力交付,即不保证可靠交付。
3. 相比较而言,从代码量及逻辑结构看,UDP程序结构较简单
centos7 安装python3 环境 https://zhuanlan.zhihu.com/p/492815893
1.2.1bash: /usr/bin/yum: 没有那个文件或目录
参照链接内容:-bash: yum: 未找到命令/-bash: yum: command not found(https://blog.tag.gg/showinfo-3-36222-0.html)
```
没有可用软件包 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:每次删除前不需要询问)依次删去不完整的即可。
很有可能没有联网
可以ping下公用网检查是否联网
若未联网,参看:linux connect: 网络不可达、没有ip解决方法
https://blog.csdn.net/weixin_45142497/article/details/127802896
在客户端接受键盘的数据,通过tcp发送到服务器,服务器显示客户端发送的数据,返回`接收到数据的时间+发送过来的数据`。客户端将服务器返回的数据打印在显示屏上。然后重复前面步骤,循环往返,知道客户打输入"exit",套接字关闭。
先启动服务端的tcp_server.py,后运行客户端的tcp_client.py
客户端:
服务器端:
2.1.2客户端
```
#允许访问server的8000端口 防止数据包被iptables防火墙拦截
#iptables -A IN_public_allow -p tcp --dport 8000 -m state --state NEW -j ACCEPT
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”
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.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)
问题描述:当我在客户端用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(在讨论区中还有另外一种解决方法——创建新线程,但我还是没有看懂)
报错截图:
原因:
原因一、项目中存在大量的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.2.1基于UDP的通信
2.2.1.1描述:
在客户端接受键盘的数据,通过udp发送到服务器,服务器显示客户端发送的数据,返回`接收到数据的时间+发送过来的数据`。客户端将服务器返回的数据打印在显示屏上。然后重复前面步骤,循环往返,知道客户打输入"exit",套接字关闭。
先启动服务端的tcp_server.py,后运行客户端的tcp_client.py
客户端:
服务器端:
2.2.2客户端
```
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”
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协议下,客户端不需要事先建立对服务器的连接,它能够直接向服务器端发送数据
两者socket()的参数不同
UDP Server不需要调用listen和accept
UDP收发数据用sendto/recvfrom函数 ,且每次均需指定地址信息
TCP的地址信息在connect/accept时确定
tcp:客户端
tcp:服务器端
udp:客户端
udp:服务器端