windows 端口占用解决方案
开发中常见,尤其是用SpringBoot开发后端程序时,就会遇到
log
***************************
APPLICATION FAILED TO START
***************************
Description:
Web server failed to start. Port 5050 was already in use.
Action:
Identify and stop the process that's listening on port 5050 or configure this application to listen on another port.
所以我记录一下我的解决方案,以及一个小TIPS
TL;DR : Too long;Don't read 文章太长了,读不下去了就看下面四行就够了
1、找pid
bash
netstat --ano | findstr 5050
2、杀pid
bash
taskkill -f -t -pid 22600
1、 查询端口
查所有端口
bash
netstat --ano
bash
结果
Active Connections
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 1356
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:1027 0.0.0.0:0 LISTENING 4964
.....
TCP 0.0.0.0:5040 0.0.0.0:0 LISTENING 7384
TCP 0.0.0.0:5520 0.0.0.0:0 LISTENING 11248
TCP 0.0.0.0:5050 0.0.0.0:0 LISTENING 22600
TCP 0.0.0.0:9999 0.0.0.0:0 LISTENING 4
查特定端口
bash
netstat --ano | findstr 5050
bash
结果
Active Connections
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:5050 0.0.0.0:0 LISTENING 22600
TCP [::]:5050 [::]:0 LISTENING 22600
UDP 0.0.0.0:5050 *:* 7648
记住此处5050端口对应的pid 22600
想查看其他netstat的参数
bash
netstat -help
显示协议统计信息和当前 TCP/IP 网络连接。
NETSTAT [-a] [-b] [-e] [-f] [-i] [-n] [-o] [-p proto] [-r] [-s] [-t] [-x] [-y] [interval]
-a 显示所有连接和侦听端口。
-b 显示创建每个连接所涉及的可执行文件或
侦听端口。在某些情况下,已知的可执行文件托管
多个独立组件,在这些情况下,将显示
创建连接
或侦听端口所涉及的组件序列。在这种情况下,可执行文件
名称位于 [] 底部,顶部是它调用的组件,
依此类推,直到达到 TCP/IP。请注意,此选项
可能很耗时,并且会失败,除非你有足够的
权限。
-c 显示按当前使用的 TCP 或 UDP
端口数排序的进程列表。
-d 显示每个连接分配的 DSCP 值。
-d 显示以太网统计信息。这可以与 -s
选项结合使用。
-f 显示外部的完全限定的域名 (FQDN)
地址。
-i 显示 TCP 连接在其当前状态下所用的时间。
-n 以数字形式显示地址和端口号。
-o 显示与每个连接关联的拥有进程 ID。
-p proto 显示 proto 指定的协议的连接;proto
可以是以下任一项: TCP、UDP、TCPv6 或 UDPv6。如果与 -s
选项一起使用以显示每个协议统计信息,则 proto 可以是以下任一项:
IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 或 UDPv6。
-q 显示所有连接、侦听端口和绑定
非侦听 TCP 端口。绑定的非侦听端口可能已与或未与
活动连接相关联。
-r 显示路由表。
-s 显示每个协议的统计信息。默认情况下,显示
IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 和 UDPv6 的统计信息;
-p 选项可用于指定默认值的子集。
-t 显示当前的连接卸载状态。
-x 显示 NetworkDirect 连接、侦听器和共享
终结点。
-y 显示所有连接的 TCP 连接模板。
无法与其他选项结合使用。
间隔 重播所选统计信息、每次显示之间的
暂停间隔秒数。按 CTRL+C 停止重新显示
统计信息。如果省略,netstat 将打印当前
配置信息一次。
2、 杀掉占用端口的进程
方案一
-
任务管理器 → 详细信息 → 点击
PID
(排序方便寻找)→ 找到PID
为 22600 的进程 → 结束进程 -
win11应该能直接搜索pid
方案二
直接通过终端杀掉占用端口的进程
- 查询进程
tasklist | findstr 进程ID
- 终止进程
taskkill -f -t -pid 进程ID
所以此处可以执行下面的命令关掉占用端口的进程
bash
taskkill -f -t -pid 22600
想查看taskkill的其他参数
bash
taskkill /?
TASKKILL [/S system [/U username [/P [password]]]]
{ [/FI filter] [/PID processid | /IM imagename] } [/T] [/F]
描述:
使用该工具按照进程 ID (PID) 或映像名称终止任务。
参数列表:
/S system 指定要连接的远程系统。
/U [domain\]user 指定应该在哪个用户上下文执行这个命令。
/P [password] 为提供的用户上下文指定密码。如果忽略,提示
输入。
/FI filter 应用筛选器以选择一组任务。
允许使用 "*"。例如,映像名称 eq acme*
/PID processid 指定要终止的进程的 PID。
使用 TaskList 取得 PID。
/IM imagename 指定要终止的进程的映像名称。通配符 '*'可用来
指定所有任务或映像名称。
/T 终止指定的进程和由它启用的子进程。
/F 指定强制终止进程。
/? 显示帮助消息。
筛选器:
筛选器名 有效运算符 有效值
----------- --------------- -------------------------
STATUS eq, ne RUNNING |
NOT RESPONDING | UNKNOWN
IMAGENAME eq, ne 映像名称
PID eq, ne, gt, lt, ge, le PID 值
SESSION eq, ne, gt, lt, ge, le 会话编号。
CPUTIME eq, ne, gt, lt, ge, le CPU 时间,格式为
hh:mm:ss。
hh - 时,
mm - 分,ss - 秒
MEMUSAGE eq, ne, gt, lt, ge, le 内存使用量,单位为 KB
USERNAME eq, ne 用户名,格式为 [domain\]user
MODULES eq, ne DLL 名称
SERVICES eq, ne 服务名称
WINDOWTITLE eq, ne 窗口标题
说明
----
1) 只有在应用筛选器的情况下,/IM 切换才能使用通配符 '*'。
2) 远程进程总是要强行 (/F) 终止。
3) 当指定远程机器时,不支持 "WINDOWTITLE" 和 "STATUS" 筛选器。
例如:
TASKKILL /IM notepad.exe
TASKKILL /PID 1230 /PID 1241 /PID 1253 /T
TASKKILL /F /IM cmd.exe /T
TASKKILL /F /FI "PID ge 1000" /FI "WINDOWTITLE ne untitle*"
TASKKILL /F /FI "USERNAME eq NT AUTHORITY\SYSTEM" /IM notepad.exe
TASKKILL /S system /U 域\用户名 /FI "用户名 ne NT*" /IM *
TASKKILL /S system /U username /P password /FI "IMAGENAME eq note*"
3、分享一个Y(歪)方案
减少系统更新带来的间隔,以前更新jar包,会关掉原来的后台jar包,然后启动当前的后台jar包,这会导致大约20s的系统停顿,所以有了下面这个类
java
@RestController
@Order(0x80000000 + 20)
public class SameLikeNotStop {
@Value("${server.port}")
private int serverPort;
private boolean isPortAvailable(int port) {
try (ServerSocket serverSocket = new ServerSocket(port)) {
return true;
} catch (Exception e) {
return false;
}
}
@PostConstruct
public void init() {
log.info("run in init !");
AtomicInteger atomicInteger = new AtomicInteger(0);
while (!isPortAvailable(serverPort)) {
ThreadUtil.safeSleep(1000);
System.out.print("\rIt has been waiting for port " + serverPort + " to be released for " + atomicInteger.incrementAndGet() + " seconds!"); // 此处不会按内容打印,只会替换其中的秒
}
System.out.println("run in init end !");
}
}
【当前控制台】会等待【当前运行的系统控制台】把接口释放掉
java
2025-08-15 15:51:19.596 [main] INFO c.s.c.SameLikeNotStop.init(33) - run in init !
It has been waiting for port 5050 to be released for 14 seconds!
这时候关掉【当前运行的系统控制台】 (ctrl + c)
【当前的启动台】就能顺利启动了,新的jar包就替换掉了原来的jar包,间隔也大约从20s-变到1s左右
4、总结
没啥好总结的。。。😂
对了还有一个一行命令解决的的方案,可以试试
bash
for /f "tokens=5" %a in ('netstat -ano ^| findstr :5050') do taskkill /PID %a /F