2009-08-06 24 views
5

Tôi hiện đang viết một ứng dụng máy chủ nhỏ và vấn đề của tôi là khi tôi đóng ứng dụng (hoặc tốt hơn, nhấn nút chấm dứt trong nhật thực), ổ cắm đôi khi vẫn giữ nguyên mở, vì vậy khi tôi thực hiện ứng dụng của mình vào lần tiếp theo, bind() sẽ thất bại với "Địa chỉ đã được sử dụng". Làm cách nào để tôi có thể đóng đúng các ổ cắm khi chương trình thoát? Tôi đã đặtỔ cắm vẫn mở sau khi chương trình đã đóng (C++)

close(mySocket); 

trong trình phá hủy lớp học, nhưng điều đó dường như không thay đổi bất cứ điều gì.

+0

Bạn có chắc chắn các trình phá hủy đang hoạt động không? Bạn có thể đặt một số đầu ra hoặc một breakpoint có để xem? –

+0

TCP được chuẩn hóa "trên dây" chứ không phải ở cấp API. Vì vậy, một trong những điều quan trọng nhất khi đặt câu hỏi liên quan đến TCP là tiết lộ nền tảng. –

Trả lời

2

http://hea-www.harvard.edu/~fine/Tech/addrinuse.html sẽ trả lời nhiều câu hỏi của bạn. Tôi có xu hướng sử dụng SO_REUSEADDR để làm việc xung quanh vấn đề đó.

+0

Ok, nếu tôi làm đúng, loại bỏ qua ổ cắm vẫn được báo cáo là đang sử dụng. Nhưng có cách nào để đóng nó ngay từ đầu không? – fresskoma

+0

Có. Gọi 'close' trên đó. – Geo

+0

Có, nhưng ở đâu. Tôi phải gọi nó ở đâu để nó được thực hiện khi ứng dụng của tôi bị chấm dứt. – fresskoma

-1

Bạn có chắc chắn ứng dụng của mình không bằng cách nào đó vẫn chạy trong nền?

+0

Vâng, khá nhiều. giết -9 chắc chắn nên tắt nó đi, phải không? Dù sao, không thể tìm thấy nó khi tôi grep trên ps -A. – fresskoma

+0

Giết -9 nên chăm sóc nó. Điều đó thật đáng ngạc nhiên. – Juan

+0

Trừ trường hợp kill -9 có nghĩa là "SHUT THIS NÀY DOWN NOW", không phải "nói điều này để tự tắt chính xác". Nó sẽ không gọi destructors. –

2

Bạn đã thiết lập các tùy chọn SO_REUSEADDR? Từ những gì bạn đang nói, có vẻ như không.

3

Sử dụng netstat để tìm ra trạng thái điểm cuối của bạn. Dự đoán của tôi là ở trạng thái TIME_WAIT và không đóng hoàn toàn. Đây là hành vi đúng đối với TCP và tồn tại để cho phép các phân đoạn đi lạc có thể vẫn còn trong ether để đến và không gây ra sự cố. Thời lượng TIME_WAIT là một cái gì đó giống như 2 * MSL, tức là gấp đôi thời gian tồn tại tối đa của một phân khúc trên mạng, do đó đảm bảo rằng ngay cả một phân đoạn được truyền lại được xử lý đúng cách.

Như những người khác đã chỉ ra, SO_REUSEADDR là bạn của bạn miễn là điểm cuối của bên kia khác nhau mỗi lần. Đó là trường hợp phổ biến, nhưng đôi khi mọi người làm những việc kỳ lạ như ràng buộc khách hàng với một cổng cụ thể và trong trường hợp đó, bạn vẫn sẽ kết thúc bằng một TCP EADDRINUSE b/c xác định phiên là cả hai điểm cuối.

0

Đừng quên kiểm tra giá trị trả lại của đóng. Nó sẽ trả về 0 khi ổ cắm được đóng thành công. Nó sẽ trả về -1 nếu nó thất bại.

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