2013-10-24 6 views
5

मुझे इस सर्वर की जरूरत है कि ग्राहकों के साथ नए कनेक्शन सुनने और स्थापित करने में सक्षम हों, साथ ही साथ मौजूदा कनेक्शनों को लिखना .. यानी। असीमित गैर-अवरुद्ध i/o। मुझे मतदान() का उपयोग करने के लिए कहा गया है लेकिन सॉकेट प्रोग्रामिंग को समझने की कोशिश करने के लिए एक अनोखा समय खर्च करने के बाद, मैं अभी भी अनिश्चित हूं कि मतदान() फ़ंक्शन को कैसे कार्यान्वित किया जाता है।एक टीसीपी सर्वर के पढ़ने/लिखने पर मतदान() को लागू करना

int sockfd; 

int main(int argc, char *argv[]) 
{ 
int newsockfd, portno; 
socklen_t clilen; 
char buffer[256];  
struct sockaddr_in serv_addr, cli_addr; 
int n;    

if (argc < 2) {   
    fprintf(stderr,"ERROR, no port provided\n"); 
    exit(1); 
} 

sockfd = socket(AF_INET, SOCK_STREAM, 0);  
if (sockfd < 0)      
    error("ERROR opening socket");   

bzero((char *) &serv_addr, sizeof(serv_addr));  

portno = atoi(argv[1]);    
serv_addr.sin_family = AF_INET;   
serv_addr.sin_addr.s_addr = INADDR_ANY;  
serv_addr.sin_port = htons(portno);  

if (bind(sockfd, (struct sockaddr *) &serv_addr, 
      sizeof(serv_addr)) < 0) 
      error("ERROR on binding");   
listen(sockfd,5);     

clilen = sizeof(cli_addr);  

while(1){   
    newsockfd = accept(sockfd, 
       (struct sockaddr *) &cli_addr, 
       &clilen);    
    if (newsockfd < 0)     
      error("ERROR on accept"); 

    // READ READ READ READ READ READ READ READ READ READ READ READ READ READ READ READ 
    bzero(buffer,256); 
    n = read(newsockfd,buffer,255);  


    if (n < 0) error("ERROR reading from socket"); 
    printf("Here is the message: %s\n",buffer); 

    // WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE 
    n = write(newsockfd,"I got your message",18); 
    if (n < 0) error("ERROR writing to socket"); 
    close(newsockfd); 
} 

return 0; 

}

मेरे समझ है कि मैं कुछ इस तरह का निर्माण करने की आवश्यकता है:

// Set up array of file descriptors for polling 
struct pollfd ufds[2]; 
ufds[0].fd = sockfd;  
ufds[0].events = POLLIN; 

ufds[1].fd = newsockfd; 
ufds[1].events = POLLOUT; 

और उपयोग सर्वेक्षण (ufds, 2,2000); लूप के अंदर यह जांचने के लिए कि क्या सॉकफड या न्यूज़ॉकएफडी में कोई गतिविधि है, इस मामले में मैं उचित पढ़ने या लिखने का उपयोग करता हूं .. अगर कोई मुझे कुछ मार्गदर्शन दे सकता है तो मैं बहुत सराहना करता हूं।

+1

क्या आपने "चयन" के बारे में पढ़ा है? – NiRR

उत्तर

3

कर्नेल struct pollfd सरणी के revents फ़ील्ड में हुई घटनाओं को भर देगा।

मैनुअल पृष्ठ से:

क्षेत्र revents एक आउटपुट पैरामीटर, घटनाओं है कि वास्तव में हुआ साथ कर्नेल द्वारा भरा है। विद्रोहियों में लौटाई गई बिट्स में घटनाओं में निर्दिष्ट किसी भी, या मूल्यों में से एक पोलरर, पोलहुप, या पोलवलल शामिल हो सकता है। (ये तीन बिट घटनाओं के क्षेत्र में व्यर्थ हैं, और जब भी संबंधित स्थिति सत्य होती है तो पुनरुत्थान क्षेत्र में सेट की जाएगी।)

यदि आप स्वीकृत कनेक्शन के लिए ईवेंट नोटिफिकेशन चाहते हैं, तो आपको या तो आरक्षित जगह की आवश्यकता है प्रत्येक कनेक्शन के लिए struct pollfd सरणी को अग्रिम या आकार बदलें।

आपको सुनने की सॉकेट को अलग करने के लिए कुछ तरीका चाहिए। आप इसे अपने सरणी के इंडेक्स शून्य में स्टोर कर सकते हैं।

int i, n; 

n = poll(ufds, num_fds_in_array, timeout_value); 

/* errors or timeout? */ 
if (n < 1) 
    ; 

for (i = 0; i < num_fds_in_array; i++) { 
    /* were there any events for this socket? */ 
    if (!ufds[i].revents) 
     continue; 

    /* is it our listening socket? */ 
    if (!i) { 
     if (ufds[0].revents & POLLIN) 
      /* call accept() and add the new socket to ufds */ 
     else 
      /* error */ 

     continue; 
    } 

    /* is there incoming data on the socket? */ 
    if (ufds[i].revents & POLLIN) 
     /* call recv() on the socket and decide what to do from there */ 
} 

POLLOUT झंडा संकेत करने के लिए जब सॉकेट पर भेजने डेटा फोन करने वाले ब्लॉक नहीं किया जाता है।

गैर-अवरुद्ध I/O के लिए, मैं एक अधिक शक्तिशाली एपीआई का उपयोग करूंगा क्योंकि इसे विश्वसनीय रूप से करने के लिए अधिक बहीखाता की आवश्यकता होती है। अगला अनुच्छेद देखें।

दुर्भाग्यवश, poll का उपयोग करते समय सहायक स्टोर के लिए सहायक प्रति कनेक्शन डेटा के लिए कोई जगह नहीं है। आपके प्लेटफ़ॉर्म के आधार पर विकल्प उपलब्ध हैं, ई। जी। लिनक्स के लिए एपोल, * बीएसडी के लिए क्यूक्यू, और विंडोज के लिए कुछ विकल्प। यदि आप संदर्भ डेटा के साथ poll का उपयोग करना चाहते हैं, तो आपको डेटा संरचना का उपयोग करना होगा जिसे फ़ाइल डिस्क्रिप्टर या सरणी अनुक्रमणिका का उपयोग करके खोजा जा सकता है।

+0

यदि आप दिखाएंगे कि यह कोड ओपीएस कोड पर कैसे लागू किया जा सकता है तो मैं बहुत खुश हूं। मेरे पास बिल्कुल वही समस्या है जिसे मैंने पढ़ा है() कमांड जो सही तरीके से ब्लॉक करते हैं, लेकिन मैं एक कनेक्शन टाइमआउट चाहता हूं। मैंने इतनी सारी चीजों की कोशिश की, लेकिन यह काम नहीं करता है। मैं तुम्हारा कोड नहीं समझता ... यूएफडीएस क्या है? क्या यह newsockfd है ?? –

0

आप libevent का उपयोग क्यों नहीं करते? यह पूरी तरह से असीमित और गैर-अवरुद्ध है। http://libevent.org/

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