2012-07-16 12 views
7

मेरे पास डेटा अधिग्रहण मॉड्यूल है जिसमें से मैं ईथरनेट पोर्ट से डेटा एकत्र करना चाहता हूं। मैं चरणों में वहां जा रहा हूं, वर्तमान में मैं क्लाइंट से सर्वर पर केवल connect करना चाहता हूं। मैंने मूल सी कोड प्राप्त करने के लिए बीज की मार्गदर्शिका का उपयोग किया है। लेकिन मैं सिर्फ इस कनेक्ट त्रुटि connect: Connection refused.सी, सॉकेट्स: कनेक्शन अस्वीकार त्रुटि

हो रही यह मुझे क्या करना है रखें:

  1. नेटवर्क IP यहाँ उल्लेख स्थैतिक IP जो मैं कॉन्फ़िगर किया गया है।

  2. पोर्ट संख्या सर्वर साइड पर और क्लाइंट साइड मैं बंदरगाह 50000.

  3. मैं निर्माण और सर्वर साइड एप्लिकेशन को चलाने के लिए और फिर पर इस आईपी से कनेक्ट से 50000 के लिए सेट है इसे करने के लिए कनेक्ट करने का प्रयास क्लाइंट साइड एप्लिकेशन चलाकर।

एक सर्वर साइड, सर्वर साइड आवेदन returns इससे पहले कि मैं ग्राहक के पक्ष अनुप्रयोग प्रारंभ के बारे में संदेह है, इसलिए मैं इसे चलाने (while(1);) ताकि मैं ग्राहक की ओर से इसे करने के लिए कनेक्ट कर सकते हैं रखना चाहिए?

क्या गलत हो रहा है क्या मैं यहां कुछ भूल रहा हूं? मदद!

मैं बहुत थोड़ा संशोधित (आईपी और पोर्ट संख्या अलग हैं) बीज के सर्वर साइड और क्लाइंट साइड यहाँ सी कोड को पेस्ट कर रहा हूँ:

Server.c

/* 
** server.c 
*/ 
#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 



int main(int argc, char *argv[]) 
{ 
    // code for a server waiting for connections 
    // namely a stream socket on port 3490, on this host's IP 
    // either IPv4 or IPv6. 
    int sockfd; 
    struct addrinfo hints, *servinfo, *p; 
    int rv; 
    memset(&hints, 0, sizeof hints); 
    hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_flags = AI_PASSIVE; // use my IP address 

    if ((rv = getaddrinfo(NULL, "50000", &hints, &servinfo)) != 0) 
    { 
     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
     exit(1); 
    } 

    // loop through all the results and bind to the first we can 
    for(p = servinfo; p != NULL; p = p->ai_next) 
    { 
     if ((sockfd = socket(p->ai_family, p->ai_socktype, 
     p->ai_protocol)) == -1) 
     { 
      perror("socket"); 
      continue; 
     } 
     if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) 
     { 
      close(sockfd); 
      perror("bind"); 
      continue; 
     } 
     break; // if we get here, we must have connected successfully 
    } 

    if (p == NULL) 
    { 
     // looped off the end of the list with no successful bind 
     fprintf(stderr, "failed to bind socket\n"); 
     exit(2); 
    } 

    freeaddrinfo(servinfo); // all done with this structure 

} 

Client.c

/* 
** client.c 
*/ 
#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 

int main(int argc, char *argv[]) 
{ 
    // code for a client connecting to a server 
    // namely a stream socket to www.example.com on port 80 (http) 
    // either IPv4 or IPv6 
    int sockfd; 
    struct addrinfo hints, *servinfo, *p; 
    int rv; 
    memset(&hints, 0, sizeof hints); 
    hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 
    hints.ai_socktype = SOCK_STREAM; 
    if ((rv = getaddrinfo("192.168.2.4", "50000", &hints, &servinfo)) != 0) 
    { 
     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
     exit(1); 
    } 
    // loop through all the results and connect to the first we can 
    for(p = servinfo; p != NULL; p = p->ai_next) 
    { 
     if ((sockfd = socket(p->ai_family, p->ai_socktype, 
     p->ai_protocol)) == -1) 
     { 
      perror("socket"); 

     continue; 
     } 
     if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) 
     { 
      close(sockfd); 
      perror("connect"); 
      continue; 
     } 
     break; // if we get here, we must have connected successfully 
    } 

    if (p == NULL) 
    { 
     // looped off the end of the list with no connection 
     fprintf(stderr, "failed to connect\n"); 
     exit(2); 
    } 

    freeaddrinfo(servinfo); // all done with this structure 

} 

उत्तर

6

आपकी सेवा आर कोड listen() और accept() कोड को सुनकर() को कॉल करके कनेक्शन के लिए "प्रतीक्षा करें" और फिर नए कनेक्शन स्वीकार करने के लिए accept() निष्पादित कर रहा है। क्या आप उदाहरण का उपयोग नहीं कर रहे हैं यह दिखाने के लिए कैसे करें? आम तौर पर आप प्रत्येक नए कनेक्शन के लिए एक नया धागा भी फोर्क करेंगे।

अधिक जानकारी के लिए http://www.linuxhowtos.org/C_C++/socket.htm देखें।

यहाँ एक अधिक पूर्ण कार्यान्वयन के लिए एक लिंक है: http://www.thegeekstuff.com/2011/12/c-socket-programming/

+0

लिंक वे एक अच्छा पढ़ा रहे हैं के लिए धन्यवाद। – HaggarTheHorrible

+0

@HeatfanJohn मैं एक कोड है कि इन किया है की जाँच की है, लेकिन एक ही समस्या परिणाम [server.c] (https://paste.ubuntu.com/25599389/) [client.c] (https:। //paste.ubuntu। com/25599391 /) – alhelal

+0

@BandaMuhammadAlHelal आपका सर्वर पोर्ट 9999 पर सुन किया जाएगा, जबकि अपने ग्राहक बंदरगाह FTP_PORT (21) से कनेक्ट करने के प्रयास कर रहा है प्रकट होता है। कनेक्ट करने के लिए पोर्ट 99 99 का उपयोग करने के लिए अपने क्लाइंट को बदलें। – HeatfanJohn

1

कृपया अपने Server.c फ़ाइल को देखो: यह सुनने फोन नहीं करता है() सब पर!
यदि लक्षित सर्वर स्पीसिफाइड पोर्ट पर नहीं सुनता है, तो यह क्लाइंट से SYN पैकेट प्राप्त करने पर आरएसटी पैकेट वापस करेगा, इसलिए कनेक्ट() "कनेक्शन से इनकार कर दिया गया" के साथ वापस आ जाएगा। सर्वर साइड पर कार्यों का

सामान्य प्रवाह सॉकेट है -> बाँध -> सुनने -> स्वीकार करते हैं:

getaddrinfo(); 
socket(); 
bind(); 
listen(); 
/* accept() goes here */ 

कृपया http://beej.us/guide/bgnet/output/html/multipage/syscalls.html#listen

3

का उल्लेख हाँ, आप सर्वर कार्यक्रम चालू रखने की जरूरत है।अपने सर्वर प्रोग्राम में आप एक पते bind() को सॉकेट socket() और बाध्य उपयोग कर बनाई गई है, अब आप इनकमिंग कनेक्शन के लिए सुन शुरू करने के लिए की जरूरत है। यह listen() कॉल के साथ किया जाता है। एक बार जब सॉकेट इनकमिंग कनेक्शन के लिए सुन रहा है आप accept() कॉल उपयोग करने के लिए वास्तव में एक कनेक्शन को स्वीकार करने और उस विशेष ग्राहक के साथ संचार के लिए सॉकेट निकलना है।

एक त्वरित उदाहरण के रूप में, के बाद freeaddrinfo आप निम्नलिखित कोड जोड़ सकते हैं:

listen(sockfd, 8); /* allow up to 8 pending connections, i.e. created but not accepted */ 
while (1) { 
    int clientfd; 
    struct sockaddr_in client_addr; 
    socklen_t client_addr_len = sizeof(struct sockaddr_in); 
    clientfd = accept(sockfd, &client_addr, &client_addr_len); 
    /* communicate with client by send()/recv() or write()/read() on clientfd */ 
    close(clientfd); 
} 

इस कोड की कमी है कि एक समय में केवल एक ही ग्राहक नियंत्रित किया जाता है है। एकाधिक एक साथ ग्राहकों को संभालने के कुछ तरीके हैं: fork(), एकाधिक धागे, या मतदान का उपयोग कर कई प्रक्रियाएं। इन प्रश्नों में से प्रत्येक मेरी राय में, इस प्रश्न के दायरे से बाहर है।

0

मैं त्रुटि हो रही थी कारण/etc/hosts फाइल में रिमोट होस्ट का प्रवेश नहीं होने के लिए "कनेक्शन से इनकार कर दिया"। प्रवेश दोनों तरफ मौजूद होना चाहिए। क्लाइंट मशीन/आदि/होस्ट में, सर्वर मशीन की प्रविष्टि होनी चाहिए और इसके विपरीत नीचे पैटर्न में होना चाहिए।

<ip address> <hostname with domain> <alias hostname>

यह त्रुटि जो मैं getaddrinfo() प्रकार्य में था हल किया।

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