2013-03-04 37 views
22

Tôi đang cố gắng để ràng buộc một ổ cắm vào một cổng bên dưới:Bind thất bại: Địa chỉ đã được sử dụng

if(bind(socket_desc,(struct sockaddr *) &server, sizeof(server)) < 0) 
{ 
    perror("bind failed. Error"); 
    return 1; 
} 
puts("bind done"); 

Nhưng nó mang lại:

$ ./serve 
Socket created  
bind failed. Error: Address already in use 

Tại sao lỗi này xảy ra?

+1

Sử dụng số cổng khác? – Nick

+2

Sử dụng địa chỉ chưa được sử dụng. –

+0

Tôi hiểu rồi .. Tôi chọn các cổng khác nhau ... Cảm ơn sự giúp đỡ .. Cảm ơn tất cả. – TamiL

Trả lời

18

Lỗi thường có nghĩa là cổng bạn đang cố gắng mở đang được ứng dụng khác sử dụng thử sử dụng netstat để xem cổng nào đang mở và sau đó sử dụng cổng khả dụng.

Đồng thời kiểm tra xem bạn có ràng buộc với địa chỉ IP phù hợp không (Tôi giả sử nó sẽ là địa chỉ IP cục bộ)

+1

Nó cũng có thể là bạn đang chạy một proxy gỡ lỗi web như fiddler (http://www.telerik.com/fiddler). Tôi đã nhận được cùng một lỗi trên máy tính của tôi, tôi đóng cửa fiddler, và đã có thể tiến hành tốt. – farskeptic

+1

Cũng có thể có các cổng còn lại trong trạng thái TIME-WAIT. Nếu địa chỉ IP sai thì lỗi sẽ không được 'gán địa chỉ được yêu cầu' và mặc định sẽ được giả định không phải là 'localhost' nhưng INADDR_ANY. – EJP

15

Bạn có một quá trình đã sử dụng cổng đó. netstat -tulpn sẽ bật một ID để tìm ID quá trình đang sử dụng một cổng cụ thể.

36

Mọi người đều chính xác. Tuy nhiên, nếu bạn cũng đang thử nghiệm mã của mình, ứng dụng của riêng bạn vẫn có thể "sở hữu" socket nếu nó bắt đầu và dừng tương đối nhanh. Hãy thử SO_REUSEADDR làm tùy chọn ổ cắm:

SO_REUSEADDR chính xác làm gì?

Tùy chọn ổ cắm này cho nhân biết rằng ngay cả khi cổng này bận (trong trạng thái TIME_WAIT ), hãy tiếp tục và sử dụng lại nó. Nếu nó bận, nhưng với một tiểu bang khác, bạn vẫn sẽ nhận được một địa chỉ đã được sử dụng lỗi. Nó rất hữu ích nếu máy chủ của bạn đã bị tắt, và sau đó khởi động lại ngay lập tức trong khi các ổ cắm vẫn hoạt động trên cổng của nó. Bạn cần lưu ý rằng nếu có bất kỳ dữ liệu nào không mong muốn, nó có thể gây nhầm lẫn máy chủ của bạn, nhưng trong khi điều này là có thể, thì điều đó là không thể.

Nó đã được chỉ ra rằng "Một socket 5 tuple (proto, địa phương addr, cảng địa phương, addr từ xa, cổng từ xa). SO_REUSEADDR chỉ nói mà bạn có thể tái sử dụng các địa chỉ địa phương. 5 tuple vẫn phải là độc đáo! " bởi Michael Hunter ([email protected]). Điều này là đúng, và điều này là là lý do tại sao rất ít dữ liệu không mong muốn sẽ được xem bởi máy chủ của bạn. Nguy hiểm là 5 bộ như vậy vẫn còn nổi xung quanh trên mạng, và trong khi nó đang nảy xung quanh, một kết nối mới từ cùng một máy khách, trên cùng một hệ thống, xảy ra để có được cùng một cổng . Điều này được giải thích bởi Richard Stevens trong `2.7 Xin vui lòng giải thích trạng thái TIME_WAIT. ''.

+1

https://easyengine.io/tutorials/nginx/troubleshooting/emerg-bind-failed-98-address-already-in-use/ Liên kết trên chỉ khắc phục được sự cố của tôi ... Mặc dù tôi đã sử dụng (SO_REUSEADDR | SO_REUSEPORT) cả hai vấn đề này đã xảy ra. –

+1

@iDebD_gh SO_REUSEPORT chỉ dành cho UDP. – EJP

+0

Lưu ý SO_REUSEADDR có thể có phân nhánh âm nếu cổng được đề cập nằm phía sau Trình cân bằng tải. – kmarsh

4

Như đã đề cập ở trên, cổng đang được sử dụng. Điều này có thể do một số lý do

  1. một số ứng dụng khác đang sử dụng nó.
  2. Cổng ở trạng thái close_wait khi chương trình của bạn đang đợi đầu kia đóng chương trình.refer (https://unix.stackexchange.com/questions/10106/orphaned-connections-in-close-wait-state).
  3. Chương trình có thể ở trạng thái time_wait. bạn có thể đợi hoặc sử dụng tùy chọn socket SO_REUSEADDR như đã đề cập trong bài đăng khác.

Làm netstat -a | grep <portno> để kiểm tra trạng thái cổng.

+6

Làm cách nào chúng tôi có thể dừng ứng dụng này theo cách thủ công tại số cổng này? – user2925949

+0

CLOSE-WAIT có nghĩa là cổng đang chờ kết thúc này để đóng nó, không phải là kết thúc từ xa. Đó là những gì liên kết của bạn nói quá. – EJP

Các vấn đề liên quan