Xung đột cổng đầy phiền toáiTuần trước, tôi đã sẵn sàng để kiểm thử một Flask API mới, nhưng macOS lại có kế hoạch khác. Thay vì dòng chữ quen thuộc 'Running on http://127.0.0.1:5000', terminal của tôi lại trả về một thông báo lỗi đầy khó chịu:
Error: listen EADDRINUSE: address already in use :::5000
Nếu bạn phát triển công cụ bằng Node.js, Python hoặc Ruby, bạn chắc hẳn đã quá quen với việc này. Thông thường, điều này có nghĩa là một tiến trình "zombie" vẫn đang bám lấy cổng của bạn. Nhưng trên các phiên bản macOS hiện đại, thủ phạm không phải là một tab terminal bị bỏ quên — mà chính là hệ điều hành đang chiếm dụng không gian làm việc của bạn.
Thủ phạm: AirPlay ReceiverKể từ macOS Monterey (phiên bản 12.0), Apple đã bật tính năng 'AirPlay Receiver' theo mặc định. Dịch vụ này lắng nghe trên các cổng 5000 và 7000 để nhận các luồng truyền phát từ iPhone hoặc iPad của bạn. Vì Flask mặc định sử dụng cổng 5000 và nhiều microservice chạy Docker dựa vào cổng 7000, 'tính năng' này gây ra rắc rối ngay lập tức cho các nhà phát triển chưa kịp điều chỉnh cài đặt AirPlay.
Bước 1: Xác nhận tiến trìnhĐừng chỉ nghe lời tôi — hãy tự mình kiểm tra trước. Mở terminal và chạy lệnh lsof để xem chính xác ai đang "cắm trại" trên cổng của bạn:
sudo lsof -i :5000
Nếu AirPlay là nguyên nhân gây ra sự xáo trộn, kết quả đầu ra của bạn sẽ trông như thế này:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ControlCe 482 user 18u IPv4 0x7b... 0t0 TCP *:commplex-main (LISTEN)
ControlCe 482 user 19u IPv6 0x7b... 0t0 TCP *:commplex-main (LISTEN)
Hãy nhìn vào cột COMMAND. Nếu nó hiển thị ControlCenter, bạn đã tìm thấy nguồn cơn. Trên macOS, Control Center xử lý phần hậu cần của AirPlay và nó sẽ không tự nguyện từ bỏ cổng đó.
Bước 2: Cách khắc phục triệt đểViệc buộc dừng tiến trình chỉ là giải pháp tạm thời. macOS được thiết kế để có khả năng phục hồi; nó sẽ đơn giản là tự khởi động lại dịch vụ như một NPC lì lợm. Để thu hồi cổng của bạn vĩnh viễn, bạn cần tắt tính năng này trong cài đặt hệ thống.
- Mở System Settings (hoặc System Preferences).- Điều hướng đến General ở thanh bên.- Nhấp vào AirPlay & Handoff.- Tìm mục AirPlay Receiver.- Tắt nó đi.Nếu bạn thực sự sử dụng AirPlay để phản chiếu màn hình điện thoại lên Mac, bạn có thể thử đổi 'Allow AirPlay for' thành 'Current User.' Tuy nhiên, theo thử nghiệm của tôi, dịch vụ này thường vẫn tiếp tục chiếm dụng cổng 5000. Vô hiệu hóa hoàn toàn là cách duy nhất đảm bảo 100% để môi trường phát triển của bạn trở lại bình thường.
Bước 3: Xác minhSau khi gạt công tắc đó, hãy quay lại terminal. Chạy lệnh kiểm tra một lần nữa:
lsof -i :5000
Sự im lặng là vàng trong trường hợp này. Nếu lệnh không trả về kết quả nào, cổng của bạn đã được giải phóng. Giờ đây bạn có thể khởi động server phát triển mà không sợ lỗi EADDRINUSE phá hỏng cuộc vui.
Giải pháp thay thế: Thay đổi cổng ứng dụngNếu bạn không thể sống thiếu AirPlay Receiver, lựa chọn duy nhất còn lại là chuyển ứng dụng của bạn sang một "khu vực" khác, như cổng 5001 hoặc 8080. Đối với ứng dụng Flask, bạn sẽ điều chỉnh lệnh khởi động như sau:
flask run --port 5001
Trong môi trường Node/Express, bạn sẽ cập nhật tệp đầu vào (entry point):
const PORT = process.env.PORT || 5001;
app.listen(PORT, () => console.log(`Server đang chạy trên cổng ${PORT}`));
Mẹo về mạng cho lập trình viênXung đột cổng là một rủi ro nghề nghiệp. Khi tôi phải xử lý nhiều container Docker hoặc định tuyến nội bộ phức tạp, tôi sử dụng IP Subnet Calculator này để giữ cho logic mạng của mình luôn chuẩn xác. Đây là một cách nhanh chóng để kiểm tra lại các khối CIDR và đảm bảo các địa chỉ dịch vụ cục bộ không bị chồng chéo gây ra các vòng lặp định tuyến kỳ lạ. Nó chạy hoàn toàn trên trình duyệt, giúp giữ kín các cấu hình mạng nội bộ của bạn.
Bằng cách dọn dẹp xung đột AirPlay ngay bây giờ, bạn sẽ tự cứu mình khỏi sự bực bội lặp đi lặp lại khi phải săn tìm các tiến trình "ma" mỗi lần khởi động lại máy Mac.

