2016-02-23 10 views
6

में यूडीपी क्लाइंट-सर्वर मैं यूडीपी का उपयोग कर क्लाइंट सर्वर प्रोग्राम लिखने की कोशिश कर रहा हूं, और प्रतीक्षा-और-स्टॉप, लेकिन मुझे उस भाग में नहीं मिला है, मैं अभी भी इसे समझने की कोशिश कर रहा हूं दो क्लाइंट प्रोग्राम (सर्वर और क्लाइंट) संवाद कैसे करते हैं, क्योंकि मेरे क्लाइंट प्रोग्राम पर, उपयोगकर्ता को सर्वर का नाम या आईपी पता, और एक पोर्ट नाम दर्ज करना होगा, और तब एक अभिव्यक्ति भेजें जो सर्वर की गणना करनी चाहिए। हालांकि, मैंने इंटरनेट में कुछ ट्यूटोरियल खोले और तदनुसार कोडिंग के बाद (या मैंने ऐसा सोचा) मैं क्लाइंट को सर्वर के साथ संवाद नहीं कर सकता। नीचे मेरा कोड है, कृपया मुझे बताएं कि मैं क्या कर रहा हूं, अगर यह bind(), sendto(), recvfrom() या socket(), या उन सभी में से है। मैं नहीं देख सकता कि वास्तव में क्या गलत है। मुझे पता है कि क्लाइंट-साइड को अनंत लूप पर नहीं चलना चाहिए, लेकिन अब तक मैं प्रोग्राम एक-दूसरे के साथ संवाद करना चाहता हूं, इसके बाद मैं अपना कोड पॉलिश करूंगा। धन्यवाद!सॉकेट प्रोग्रामिंग: सी

क्लाइंट-साइड कोड:

#include <stdio.h>  // Default System Calls 
#include <stdlib.h>  // Needed for OS X 
#include <string.h>  // Needed for Strlen 
#include <sys/socket.h> // Needed for socket creating and binding 
#include <netinet/in.h> // Needed to use struct sockaddr_in 
#include <time.h>  // To control the timeout mechanism 

#define EXPR_SIZE 1024 
#define BUFLEN  512 
#define TRUE  1 
#define FALSE  0 
#define SERVERLEN 1024 

int main(int argc, char **argv){ 

    long portNum;   // Since it's possible to input a value bigger 
          // than 65535 we'll be using long to 
          // avoid overflows 
    char expr[EXPR_SIZE]; 
    char server[SERVERLEN]; 
    int fd;     // file descriptor for the connected socket 
    int buf[512]; 
    struct hostent *h;   // information of the host 
    unsigned int addrLen;  // address length after getting the port number 
    struct sockaddr_in myaddr; // address of the client 
    struct sockaddr_in servaddr; // server's address 
    unsigned int exprLen; 
    socklen_t slen = sizeof(servaddr); 

    printf("Enter server name or IP address:"); 
    scanf("%s",server); 
    printf("Enter port:"); 
    scanf("%ld",&portNum); 
    if ((portNum < 0) || (portNum > 65535)) { 
     printf("Invalid port number. Terminating."); 
     return 0; 
    } 
    printf("Enter expression:"); 
    scanf("%s",expr); 

    if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ 
     perror("cannot create socket"); 
     return 0; 
    } 

    memset((char *)&myaddr, 0, sizeof(myaddr)); 
    myaddr.sin_family = AF_INET; 
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    myaddr.sin_port = htons(0); 

    if(bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0){ 
     perror("cannot bind"); 
     return 0; 
    } 

    /* 
    // Discovering the port number the OS allocated 
    addrLen = sizeof(myaddr); 
    if(getsockname(fd, (struct sockaddr *)&myaddr, &addrLen) < 0){ 
    perror("cannot getsockname"); 
    return 0; 
    } 
    printf("local port number = %d\n", ntohs(myaddr.sin_port)); 
    */ 

    memset((char*)&servaddr, 0, sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_port = htonl(portNum); 

    exprLen = sizeof(expr); 


    while(TRUE){ 
     printf("Sending message to %s port %ld\n",server, portNum); 
     if (sendto(fd, expr, strlen(expr), 0, (struct sockaddr *)&servaddr, slen) < 0) { 
      perror("cannot sendto()"); 
     } 
     printf("Success\n"); 

    } 


    return 0; 
} 

सर्वर साइड कोड:

#include <stdio.h>  // Default System Calls 
#include <stdlib.h>  // Needed for OS X 
#include <string.h>  // Needed for Strlen 
#include <sys/socket.h> // Needed for socket creating and binding 
#include <netinet/in.h> // Needed to use struct sockaddr_in 
#include <time.h>  // To control the timeout mechanism 

#define EXPR_SIZE 1024 
#define BUFLEN  512 
#define TRUE  1 
#define SERVERLEN 1024 

int main(int argc, char **argv){ 

    struct sockaddr_in myaddr; // address of the server 
    struct sockaddr_in claddr; // address of the client 
    char buf[BUFLEN]; 
    int fd; 
    long recvlen; 
    socklen_t clientlen; 



    if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ 
     perror("cannot create socket"); 
     return 0; 
    } 

    memset((char *)&myaddr, 0, sizeof(myaddr)); 
    myaddr.sin_family = AF_INET; 
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    myaddr.sin_port = htons(0); 

    if(bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0){ 
     perror("cannot bind"); 
     return 0; 
    } 
    clientlen = sizeof(claddr); 

    while (TRUE) { 
     recvlen = recvfrom(fd, buf, BUFLEN, 0, (struct sockaddr *)&claddr, &clientlen); 
     if (recvlen < 0) { 
      perror("cannot recvfrom()"); 
      return 0; 
     } 
     printf("Received %ld bytes\n",recvlen); 
     buf[recvlen] = 0; 
     printf("Received message: \"%s\"\n",buf); 

    } 

    return 0; 
} 

सर्वर कार्यक्रम नहीं है उत्पादन कुछ भी है, जबकि ग्राहक आउटपुट जब तक प्रक्रिया में बाधा आती है:

Enter server name or IP address:127.0.0.1 
Enter port:30 
Enter expression:2+2 
Sending message to 127.0.0.1 port 30 
cannot sendto(): Can't assign requested address 

मैंने सर्वर नाम को स्थानीयहोस्ट और अन्य बंदरगाहों में बदलने की कोशिश की, लेकिन इसका कोई फायदा नहीं हुआ।

+2

है "मैं ग्राहक सर्वर के साथ संवाद नहीं कर सकता।"। क्या आप इससे थोड़ा विशिष्ट हो सकते हैं? क्या प्रोग्राम क्रैश होता है, क्या यह कोई आउटपुट नहीं बनाता है, क्या यह गलत आउटपुट उत्पन्न करता है? इत्यादि। किसी भी डिबगिंग निष्कर्ष भी शामिल करें जिन्हें आप पहले ही एकत्र कर चुके हैं। – kaylum

+0

प्रश्न –

+1

में आउटपुट को संपादित करने के लिए जा रहे हैं आपके क्लाइंट को उसी पोर्ट को भेजने की आवश्यकता है जिसे सर्वर ने बाध्य किया है। क्लाइंट में इस पंक्ति के लिए – kaylum

उत्तर

12

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

ग्राहक पक्ष पर, चीजों को ध्यान में रखते हुए सरल साधन

  • ग्राहक में bind फोन न करें। ओएस एक उपयुक्त इंटरफेस का चयन करेगा और एक यादृच्छिक पोर्ट नंबर असाइन करेगा, इसलिए bind सॉकेट की आवश्यकता नहीं है।

  • हार्ड-कोड किए गए सर्वर पते का उपयोग करें (उदा। 127.0.0.1)। पता 127.0.0.1 (0x7f000001) स्थानीय होस्ट पता है, जो एक ही मशीन पर किसी सर्वर पर पैकेट भेजने के लिए उपयुक्त है।

  • हार्ड-कोडित पोर्ट नंबर (उदा। 50037) का उपयोग करें। Ephemeral port numbers 0xC000 हेक्स (49152 दशमलव) से अधिक होना चाहिए।

  • हार्ड-कोड किए गए संदेश का उपयोग करें, उदा। "नमस्ते"।

इसे ध्यान में रखते

, यहाँ क्लाइंट सॉफ्टवेयर, जैसे

int main(void) 
{ 
    int fd; 
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 
     perror("socket failed"); 
     return 1; 
    } 

    struct sockaddr_in serveraddr; 
    memset(&serveraddr, 0, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_port = htons(50037);    
    serveraddr.sin_addr.s_addr = htonl(0x7f000001); 

    for (int i = 0; i < 4; i++) { 
     if (sendto(fd, "hello", 5, 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) { 
      perror("sendto failed"); 
      break; 
     } 
     printf("message sent\n"); 
    } 

    close(fd); 
} 

सर्वर साइड पर लग रहा है क्या चीजों को सरल साधन

  • बाइंड INADDR_ANY, यानी करने के लिए ओएस ले जाने रखने है एक उपयुक्त इंटरफेस।
  • एक हार्ड-कोडित बंदरगाह से बांधें, उदा। 50037 (क्लाइंट का उपयोग करने वाला वही पोर्ट होना चाहिए)।
  • recvfrom से पता जानकारी का अनुरोध न करें, यानी पिछले दो पैरामीटर के रूप में NULL, 0 पास करें।
इसे ध्यान में रखते

, यहाँ क्या सर्वर सॉफ्टवेयर लगता है कि

int main(void) 
{ 
    int fd; 
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 
     perror("socket failed"); 
     return 1; 
    } 

    struct sockaddr_in serveraddr; 
    memset(&serveraddr, 0, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_port = htons(50037); 
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    if (bind(fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) { 
     perror("bind failed"); 
     return 1; 
    } 

    char buffer[200]; 
    for (int i = 0; i < 4; i++) { 
     int length = recvfrom(fd, buffer, sizeof(buffer) - 1, 0, NULL, 0); 
     if (length < 0) { 
      perror("recvfrom failed"); 
      break; 
     } 
     buffer[length] = '\0'; 
     printf("%d bytes: '%s'\n", length, buffer); 
    } 

    close(fd); 
} 
+0

"खिलौना" अनुप्रयोगों में मुझे संदेह है कि कोई भी एक बरौनी बल्लेबाजी करेगा, लेकिन सामान्य रूप से: क्षणिक बंदरगाहों का उपयोग न करें। यदि आप विषय पर Google हैं तो आपको ऐसे मामले मिलेंगे जहां लोगों ने ऐसा किया है और समस्याएं हैं, या आप केवल उनकी सलाह ले सकते हैं: http://books.google.si/books?id=Pm4RgYV2w4YC&pg=PA705&lpg=PA705&dq=use%20Ephemeral % 20port% 20For% 20server और स्रोत = बीएल और ओ टी एस = qwnYpJGseD और sig = 3EihPoqMeNH06ge5lChaRmi9hFg & hl = hi & सा = एक्स और Ei = JoZsU4GBJ4iL7Ab-yICYCA और redir_esc = y # v = onepage & q = का उपयोग% 20Ephemeral% 20port% 20For% 20server & f = झूठी –

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