2010-03-01 16 views
10

संपादित करें: कोड नीचे प्राप्त करते हैं और ठीक से संदेश भेजने और की वास्तविक बाइट्स के लिए खाते के लिए निर्धारित किया गया है annd प्राप्त भेजा (EJP के बाद धन्यवाद)सॉकेट प्रोग्रामिंग: recv/पढ़ मुद्दा

मैं यूनिक्स में सी के साथ प्रोग्रामिंग।

मेरे पास सर्वर और क्लाइंट है जो संदेश का आदान-प्रदान करना है। जबकि क्लाइंट संदेश ठीक से प्रतीत होता है, सर्वर क्लाइंट भेज रहा संदेश प्राप्त नहीं करता है। मैंने recv() और read() का उपयोग करने का प्रयास किया है (मुझे पता है कि वे व्यावहारिक रूप से एक ही चीज़ हैं लेकिन recv() पर अतिरिक्त झंडे के साथ) लेकिन मुझे कोई भाग्य नहीं है और मुझे सच में यकीन नहीं है कि वास्तव में समस्या क्या है।

मैंने क्लाइंट कोड में sleep(3) डाल दिया है जब भी यह संदेश भेजता है लेकिन मुझे लगता है कि क्लाइंट और सर्वर कनेक्ट होने के बाद, सर्वर आने वाले संदेशों की प्रतीक्षा किए बिना तुरंत बंद हो जाता है। मैं क्या गलत कर रहा हूं?

यह क्लाइंट साइड कोड है:

#define SERVER_TCP_PORT 11112 
#define MAX_DATA_SIZE 500 

int main(int argc, char * argv[]) 
{ 
    int sockfd; 
    char * host; 
    char msg[MAX_DATA_SIZE];/* = "get my msg!\n";*/ 
    int msg_len; 

    struct hostent * hp; 
    struct sockaddr_in client_address, server_address; 


    printf("y halo thar\n"); 


    // looking up from the host database 
    if (argc == 2) 
     host = argv[1]; 
    else 
     exit(1); 
    printf("sdf\n"); 


    hp = gethostbyname(host); 
    if (!hp) 
     exit(1); 
    printf("host found\n"); 


    // setting up address and port structure information 
    bzero((char *) &server_address, sizeof(server_address)); // copy zeroes into string 
    server_address.sin_family = AF_INET; 
    bcopy(hp->h_addr, (char *) &server_address.sin_addr, hp->h_length); 
    server_address.sin_port = htons(SERVER_TCP_PORT); 
    printf("set\n"); 


    // opening up socket 
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
     exit(1); 
    printf("opened\n"); 


    // connecting 
    if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) 
     exit(1); 
    printf("connected\n"); 


    int i; 

    for (i = 0; i < MAX_DATA_SIZE; ++i) 
    { 
     msg[i] = '.'; 
    } 

    msg[MAX_DATA_SIZE-1] = '\0'; 

    for(i = 0; i < 11; i++) 
    { 
     // send message to connected socket 
     msg_len = write(sockfd, msg, MAX_DATA_SIZE); 
     if(msg_len < 1) 
      printf("notsent\n"); 
     else 
      printf("%i bytes sent\n", msg_len); 

     // recieve messages from connected socket 
     msg_len = read(sockfd, msg, MAX_DATA_SIZE); 
     if (msg_len < 1) 
      printf("not recieved\n"); 
     else 
     { 
      printf("%i bytes received\n", msg_len); 
      printf(msg); 
      printf("\n"); 

     } 
    } 


    // close connection 
    close(sockfd); 
    printf("closed\n"); 

} 

और इस सर्वर साइड

#define SERVER_TCP_PORT 11112 
#define MAX_DATA_SIZE 500 


int main() 
{ 

    printf("o halo thar\n"); 

    int sockfd, new_sockfd; 
    int client_addr_len; 
    char msg [MAX_DATA_SIZE]; 
    int msg_len; 
    char got_msg [11] = "got ur msg\0"; 
    struct sockaddr_in server_address, client_address; 


    // setting up address and port structure information 
    bzero((char *) &server_address, sizeof(server_address)); // copy zeroes into string 
    server_address.sin_family = AF_INET; 
    server_address.sin_addr.s_addr = htonl(INADDR_ANY); 
    server_address.sin_port = htons(SERVER_TCP_PORT); 


    // opening up socket 
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
     exit(1); 
    printf("socket is opened\n"); 


    // binding 
    if (bind(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) 
     exit(1); 
    printf("socket is bound\n"); 


    // listening 
    listen(sockfd,5); 
    printf("listening\n"); 

    // block and wait for an incoming connection 

    client_addr_len = sizeof(client_address); 
    new_sockfd = accept(sockfd, (struct sockaddr *) &client_address, &client_addr_len); 
    if (new_sockfd < 0) 
     exit(1); 

    printf("accepted\n"); 


    int i; 

    for(i = 0; i < 11; i++) 
    { 
     // recieve messages from connected socket 
     printf("waiting\n"); 
     msg_len = read(new_sockfd, msg, MAX_DATA_SIZE); 
     if (msg_len < 1) 
     { 
      printf("no msg recieved\n");  
     } 
     else 
     { 
      printf("bytes recieved: %i\n", msg_len); 
     } 


     // send message to connected socket 
     msg_len = write(new_sockfd, got_msg, sizeof(got_msg)); 
     if (msg_len < 1) 
      printf("not sent\n"); 
     else 
      printf("%i bytes sent\n", msg_len); 
    } 


    // close connection 
    close(sockfd); 
    printf("socket closed. BYE! \n"); 


} 

उत्तर

10

सर्वर कोड में, समस्या इस लाइन पर है:

msg_len = read(sockfd, msg, MAX_DATA_SIZE); 

आप readsockfd पर बुला रहे हैं, लेकिन आप new_sockfd पर read या recv (सॉकेट accept() द्वारा दिया) कॉल करने के लिए की जरूरत है। new_sockfd वह क्लाइंट से जुड़ा हुआ है (sockfd का उपयोग आगे कनेक्शन स्वीकार करने के लिए किया जाता है - उदाहरण के लिए यदि कोई अन्य क्लाइंट कनेक्ट होता है)।

+0

धन्यवाद कि समस्या हल हो गई !!! और हाँ, जो स्वीकार्य() से नई सॉकेट फ़ाइल डिस्क्रिप्टर से पढ़ने के लिए बहुत अधिक समझ में आता है। –

+2

आप त्रुटियों के लिए उन्हें जांचने के अलावा पढ़ने() और लिखने() द्वारा लौटाई गई गणनाओं को भी अनदेखा कर रहे हैं। आप ऐसा नहीं कर सकते: आपको यह निर्धारित करने के लिए उनका उपयोग करना होगा कि वास्तव में कितना डेटा पढ़ा या लिखा गया था। आप यह नहीं मान सकते कि आपका अनुरोध पूरी तरह से पूरा हो गया है। – EJP

+0

ईजेपी कोड अब भेजा और प्राप्त संदेश के वास्तविक बाइट्स के लिए खाता है। धन्यवाद। –

-1

स्ट्रीम या आंकड़ारेख के आधार पर कार्यान्वयन कर रहा है?

आपके ऑपरेशन प्रवाह में कुछ समस्या है। क्लाइंट कुछ भी भेजने से पहले सर्वर पढ़ना शुरू कर सकता है।

क्लाइंट और सर्वर अलग होने के बाद, आप कल्पना कर सकते हैं कि वे एक साथ चल रहे हैं। आपके सर्वर की ओर से "अनुरोध" कनेक्शन अनुरोध के ठीक बाद, हो सकता है कि संभवतः कुछ हैंडशेक ओवरहेड होता है या समय में सर्वर एप को निष्पादित करने में नेटवर्क देरी हो सकती है, डेटा निकालने का प्रयास किया जाता है लेकिन त्रुटियों से मिलता है (अभी तक कोई डेटा प्राप्त नहीं हुआ है)। कनेक्शन स्वीकार करने के बाद आप सर्वर कोड में नींद जोड़कर इसे आजमा सकते हैं, जहां ग्राहक को डेटा भेजने के लिए पर्याप्त समय होना चाहिए।

एक और बेहतर समाधान डेटा पुनर्प्राप्ति को खाली बफर या एसिंक्रोनस पढ़ने के साथ सामना करना है।

+0

कोई समस्या सर्वर बुला के साथ है 'ग्राहक से पहले read' कुछ भी भेजता है। 'रीड' कॉल डेटा तक उपलब्ध होने तक बस अवरुद्ध होगा। "अभी तक कोई डेटा प्राप्त नहीं हुआ" ** ** एक त्रुटि नहीं है। – caf

+0

और नींद की कोई आवश्यकता नहीं है। – EJP

+0

मैंने क्लाइंट पक्ष में केवल नींद() को जोड़ा, यह पता लगाने के लिए कि समस्या क्या थी, लेकिन मैं वास्तव में (और नहीं होना चाहिए) नींद() का उपयोग नहीं कर सकता क्योंकि इस कार्यक्रम के उद्देश्य पैकेट दौर यात्रा को मापना है। –

0

आपको accept द्वारा वापस सॉकेट से पढ़ना चाहिए।

पर पर accept पर वापस आने का प्रयास करें।

+0

क्लाइंट द्वारा भेजा गया संदेश स्पष्ट रूप से '' 'अक्षर से शुरू होता है। – caf

+0

ओह, मैं कोड के गलत हिस्से को देख रहा था – stefanB

0

संदेश साइड:

while(!feof(fp)) 
{ 
    len=fread(buff,sizeof(char),MW,fp); 
    if(len==0) 
    { 
     //EOF 
     st=write(cd,&d,sizeof(int));  
     break; 
    } 
    else 
    { 
     st=write(cd,buff,len); 
    } 
} 
0

रिसीवर साइड:

while(1) 
    {  
     len=read(sd,buff,sizeof(buff)); 

     if(len==0) 
     { 
      //End of File receving.    

      break; 
     } 
     else  
     { 
      st=fwrite(buff,sizeof(char),len,fp); 

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