2010-02-05 39 views
10

Tôi có một ổ cắm nghe trên một số cổng. Tôi gửi tín hiệu SIGSTOP tới luồng chờ trên cổng (sử dụng chấp nhận) và chấm dứt nó. sau đó tôi đóng fd của ổ cắm mà tôi đã đợi. Nhưng cho lần chạy tiếp theo của dự án của tôi, nó không cho phép tôi nghe lại trên cổng đó nữa. Chương trình của tôi nằm trong C++ dưới Linux. Tôi nên làm gì?Ổ cắm nghe không unbind trong C + + theo linux

Một số phần của mã của tôi là: Chủ đề 1:

void* accepter(void *portNo) { 
int newsockfd; 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) { 
perror("ERROR opening socket"); 
} 
struct sockaddr_in server; 
bzero((char *) & server, sizeof (server)); 
server.sin_family = AF_INET; 
server.sin_port = htons(*(int*) portNo); 
server.sin_addr.s_addr = INADDR_ANY; 
if (bind(sockfd, (struct sockaddr *) & server, sizeof (struct sockaddr_in)) < 0) { 
perror("ERROR on binding"); 
} 

listen(sockfd, 50); 
while (true) { 
struct sockaddr_in client; 
socklen_t clientLen = sizeof (struct sockaddr_in); 
newsockfd = accept(sockfd, (struct sockaddr *) & client, &clientLen); 
if (accepterFlag) { 
    break; 
} 
if (getpeername(newsockfd, (sockaddr *) & client, &clientLen) == -1) { 
    perror("getpeername() failed"); 
} 
sem_wait(setSem); 
FD_SET(newsockfd, &set); 
if (maxFd < newsockfd) { 
    maxFd = newsockfd; 
} 
sem_post(setSem); 
} 

Chủ đề 2:

listenerFlag = true; 
accepterFlag = true; 
sleep(1); 
pthread_kill(listenerThread, SIGSTOP); 
pthread_kill(accepterThread, SIGSTOP); 
close(sockfd); 
sem_wait(setSem); 
for (int i = 1; i <= maxFd; i++) { 
if (FD_ISSET(i, &set)) { 
    close(i); 
} 
} 
sem_post(setSem); 

Cảm ơn bạn.

+0

Có thể thử đóng fd của ổ cắm bên trong chuỗi chấp nhận vì nó đang kết thúc? –

+1

Bạn có chắc chắn muốn gửi 'SIGSTOP'? Có ai sẽ gửi 'SIGCONT' sau không? Tôi sẽ không ngạc nhiên nếu ổ cắm cuối cùng có thể không được đóng miễn là một số (dừng) thread vẫn còn bên trong một cuộc gọi 'accept' trên ổ cắm đó. (Bạn nói rằng bạn cũng chấm dứt chủ đề, tôi chỉ không thấy điều đó.) –

Trả lời

21

Bạn có biết rằng ổ cắm thường được giữ trong một loại tình trạng lấp lửng cho một hoặc hai phút sau khi bạn đã hoàn tất lắng nghe trên họ để ngăn chặn thông tin liên lạc dành cho quá trình trước khi đến bạn? Nó được gọi là trạng thái 'TIME_WAIT'.

Nếu bạn muốn ghi đè hành vi đó, hãy sử dụng setsockopt để đặt cờ SO_REUSEADDR vào ổ cắm trước khi nghe.

+4

Ngoài ra kiểm tra SO_LINGER. http://www.developerweb.net/forum/archive/index.php/t-2982.html – jfawcett

+0

Tôi biết rằng trong Java. Nó có giống với C++ không? – Shayan

+3

Có, đó là một điều TCP chứ không phải là một điều ngôn ngữ để nó áp dụng ở khắp mọi nơi. –

1

Tôi nghĩ vấn đề là bạn chưa đúng cách đóng ổ cắm và/hoặc ổ cắm program.The của bạn có thể vẫn tồn tại trong hệ điều hành. kiểm tra nó với một cái gì đó như nestat -an. Bạn cũng nên kiểm tra xem quy trình của bạn đã thoát hay chưa. Nếu nó đã kết thúc một cách chính xác, nó sẽ phải đóng ổ cắm của bạn.

gì bạn cần làm là:

  • ngắt thread của bạn với một tín hiệu.
  • khi ngắt chuỗi của bạn nên đóng sạch ổ cắm trước khi kết thúc.
  • thì bạn có thể thoát khỏi chương trình của mình một cách sạch sẽ.

my2cents,

+0

Xem câu hỏi đã chỉnh sửa. – Shayan

+0

Ok. Sau đó SO_REUSEADDR là chìa khóa :-) – neuro

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