[HTTP] Could not start REST http interface listener. The requested port may already be in use. Please make sure there is no other instance of this server running already.
uncaughtException: listen EADDRINUSE 127.0.0.1:4723
针对以上这种情况,我们在启动appium服务前该如何检测端口是否可用呢?对于被占用的端口我们又该如何释放?
需求分析
自动检测端口是否被占用
如果端口被占用则自动关闭对应端口的进程
端口检测
端口检测需要使用到socket模块来校验端口是否被占用。
python socket模块官方文档
什么是socket?
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。建立网络通信连接至少要一对端口号(socket)。
socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
例如当你用浏览器打开我要自学网主页时,你的浏览器会创建一个socket并命令它去连接 自学网的服务器主机,服务器也对客户端的请求创建一个socket进行监听。两端使用各自的socket来发送和接收信息。在socket通信的时候,每个socket都被绑定到一个特定的IP地址和端口。
补充资料: 网络工程师视频教程
代码实现
check_port.py
import socket
def check_port(host, port):
"""检测指定的端口是否被占用"""
#创建socket对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((host, port))
s.shutdown(2)
except OSError as msg:
print(\'port %s is available! \' %port)
print(msg)
return True
else:
print(\'port %s already be in use !\' % port)
return False
if __name__ == \'__main__\':
host=\'127.0.0.1\'
port=4723
check_port(host,port)
方法
shutdown(self, flag):禁止在一个Socket上进行数据的接收与发送。利用shutdown()函数使socket双向数据传输变为单向数据传输。shutdown()需要一个单独的参数, 该参数表示了如何关闭socket
参数
0表示禁止将来读;
1表示禁止将来写
2表示禁止将来读和写。
当端口可以使用时,控制台输出如下:此使说明服务端没有开启这个端口服务,所以可用。
C:\Python35\python.exe E:/AppiumScript/advance/appium_cmd/appium_multiProcess.py
port 4723 is available!
[WinError 10061] 由于目标计算机积极拒绝,无法连接。
Process finished with exit code 0
端口释放
如果端口被占用,则需要释放该端口。那么怎么样去释放被占用的端口呢?
代码实现
check_port.py
import os
def release_port(port):
"""释放指定的端口"""
#查找对应端口的pid
cmd_find=\'netstat -aon | findstr %s\' %port
print(cmd_find)
#返回命令执行后的结果
result = os.popen(cmd_find).read()
print(result)
if str(port) and \'LISTENING\' in result:
#获取端口对应的pid进程
i=result.index(\'LISTENING\')
start=i+len(\'LISTENING\')+7
end=result.index(\'\n\')
pid=result[start:end]
# 关闭被占用端口的pid
cmd_kill=\'taskkill -f -pid %s\' %pid
print(cmd_kill)
os.popen(cmd_kill)
else:
print(\'port %s is available !\' %port)
if __name__ == \'__main__\':
host=\'127.0.0.1\'
port=4723
# check_port(host,port)
release_port(port)
控制台显示:
C:\Python35\python.exe E:/AppiumScript/advance/appium_cmd/appium_multiProcess.py
netstat -aon | findstr "4723"