2010-02-05 12 views
10

के तहत सी ++ में अनबाइंड नहीं करता है मेरे पास एक पोर्ट है जो कुछ बंदरगाह पर सुनता है। मैं थ्रेड पर सिग्स्टॉप सिग्नल भेजता हूं जो बंदरगाह पर प्रतीक्षा करता है (स्वीकृति का उपयोग करके) और इसे समाप्त कर देता है। तो मैं उस सॉकेट का एफडी बंद करता हूं जिस पर मैंने इंतजार किया था। लेकिन मेरे प्रोजेक्ट के अगले भाग के लिए यह मुझे उस बंदरगाह पर फिर से सुनने की इजाजत नहीं देता है। मेरा प्रोग्राम लिनक्स के तहत सी ++ में है। मुझे क्या करना चाहिए?सॉकेट सुनो लिनक्स

मेरी कोड के कुछ भागों हैं: थ्रेड 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); 
} 

थ्रेड 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); 

धन्यवाद।

+0

शायद स्वीकार्य थ्रेड के अंदर सॉकेट के fd को बंद करने का प्रयास करें क्योंकि यह समाप्त हो रहा है? –

+1

क्या आप वाकई 'सिगस्टॉप' भेजना चाहते हैं? क्या कोई बाद में 'सिगकंट' भेज रहा है? मुझे आश्चर्य नहीं होगा अगर सॉकेट को तब तक बंद नहीं किया जा सकता जब तक कि कुछ (बंद) थ्रेड अभी भी उस सॉकेट पर 'स्वीकृति' कॉल के अंदर नहीं है। (आपने कहा था कि आपने धागे को भी समाप्त कर दिया है, मुझे बस यह नहीं दिख रहा है।) –

उत्तर

21

क्या आप जानते हैं कि आम तौर पर सॉकेट के बाद आप उन पर सुन पिछले प्रक्रिया तुम्हारा करने के लिए आने के लिए इरादा संचार को रोकने के लिए समाप्त करने के बाद एक या दो मिनट के लिए लीम्बो की एक किस्म में रखा जाता है? इसे 'TIME_WAIT' स्थिति कहा जाता है।

यदि आप उस व्यवहार को ओवरराइड करना चाहते हैं तो setsockopt सॉकेट के खिलाफ SO_REUSEADDR ध्वज सेट करने से पहले इसे सुनने के लिए उपयोग करें।

+4

भी SO_LINGER जांचें। http://www.developerweb.net/forum/archive/index.php/t-2982.html – jfawcett

+0

मुझे पता था कि जावा में। क्या यह सी ++ के लिए समान है? – Shayan

+3

हां, यह भाषा की बजाय एक टीसीपी चीज है, इसलिए यह हर जगह लागू होता है। –

1

मुझे लगता है कि समस्या यह है कि आप ठीक ढंग से सॉकेट नहीं बंद कर दिया है और/या अपने कार्यक्रम सॉकेट शायद अभी भी ओएस में मौजूद है। इसे nestat -an जैसे कुछ के साथ जांचें। आपको यह भी जांचना चाहिए कि आपकी प्रक्रिया समाप्त हो गई है या नहीं। यदि यह सही ढंग से समाप्त हो गया है, तो इसे आपकी सॉकेट बंद करनी चाहिए थी।

क्या करना चाहिए है:

  • एक संकेत के साथ अपने धागा बीच में।
  • जब आपके धागे को बाधित करता है तो अंत से पहले सॉकेट को साफ रूप से बंद करना चाहिए।
  • तो आप अपने प्रोग्राम से साफ़ रूप से बाहर निकल सकते हैं।

my2cents,

+0

संपादित प्रश्न देखें, कृपया। – Shayan

+0

ठीक है। फिर SO_REUSEADDR कुंजी है :-) – neuro

संबंधित मुद्दे