मैं एक छोटा सी क्लाइंट/सर्वर एप्लिकेशन लिख रहा हूं, लेकिन बाहरी आईपी पते का उपयोग करते समय मैं कनेक्शन काम नहीं कर सकता। दोनों क्लाइंट और सर्वर के लिए कोड here से लिया जाता है, विशेष रूप से ग्राहकों को कार्य करें:बाह्य आईपी का उपयोग कर सर्वर से कनेक्ट करने के लिए getaddrinfo का उपयोग कैसे करें?
char *default_server_name = "localhost";
char *server_name = NULL;
int nport = DEFAULT_DAMA_PORT;
char port[15];
// Parse the command line options
if (parse_options(argc, argv, &server_name, &nport) < 0) {
return -1;
}
if (server_name == NULL) {
server_name = default_server_name;
}
snprintf(port, 15, "%d", nport);
// Connect to the server
int client_socket;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo(server_name, port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}
for (p=servinfo; p != NULL; p = p->ai_next) {
if ((client_socket = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
#ifdef DEBUG
perror("socket");
#endif
continue;
}
if (connect(client_socket, p->ai_addr, p->ai_addrlen) == -1) {
close(client_socket);
#ifdef DEBUG
perror("connect");
#endif
continue;
}
// Connected succesfully!
break;
}
if (p == NULL) {
// The loop wasn't able to connect to the server
fprintf(stderr, "Couldn't connect to the server\n.");
exit(1);
}
सर्वर जबकि:
int nport;
char port[15];
if (parse_options(argc, argv, &nport) < 0) {
return -1;
}
snprintf(port, 15, "%d", nport);
int server_socket;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}
for (p=servinfo; p != NULL; p = p->ai_next) {
if ((server_socket = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
#ifdef DEBUG
perror("socket");
#endif
continue;
}
if (bind(server_socket, p->ai_addr, p->ai_addrlen) == -1) {
close(server_socket);
#ifdef DEBUG
perror("bind");
#endif
continue;
}
// We binded successfully!
break;
}
if (p == NULL) {
fprintf(stderr, "failed to bind socket\n");
exit(2);
}
int pl_one, pl_two;
socklen_t pl_one_len, pl_two_len;
struct sockaddr_in pl_one_addr, pl_two_addr;
if (listen(server_socket, 2) < 0) {
fatal_error("Error in syscall listen.", 2);
}
// Get the two clients connections.
pl_one_len = sizeof(pl_one_addr);
pl_one = accept(server_socket,
(struct sockaddr *)&pl_one_addr,
&pl_one_len);
if (pl_one < 0) {
fatal_error("Error in syscall accept.", 3);
}
pl_two_len = sizeof(pl_two_addr);
pl_two = accept(server_socket,
(struct sockaddr *)&pl_two_addr,
&pl_two_len);
if (pl_two < 0) {
fatal_error("Error in syscall accept.", 3);
}
अगर मैं आदेश पंक्ति में मेरी मशीन का IP निर्दिष्ट करें, और इसलिए ग्राहकों में server_name
151.51.xxx.xxx
जैसी स्ट्रिंग पर सेट है, तो सॉकेट सर्वर से कनेक्ट नहीं हो सकते हैं।
होस्ट नाम है कि आप में रुचि रखते हैं nodename पैरामीटर में चला जाता है: इसके अलावा
127.0.0.1
का उपयोग कर एक ही व्यवहार है, जो मुझे लगता है कि जब प्रलेखन राज्यों में आता है पता चलता है। पता या तो होस्ट नाम हो सकता है, जैसे "www.example.com", या एक आईपीवी 4 या आईपीवी 6 पता (एक स्ट्रिंग के रूप में पारित)।
यह सिर्फ मजाक कर रहा है।
क्या मैं कुछ गलत तरीके से कर रहा हूं? क्या फ़ायरवॉल इत्यादि के साथ कुछ समस्या हो सकती है जो ग्राहकों को आईपी पते का उपयोग करके कनेक्ट करने से रोक रही है?
नोट: मैं पहले से ही इस समस्या के लिए एक बहुत खोज की है और कुछ लोगों को बिल्कुल भी getaddrinfo
का उपयोग कर से बचने के लिए और सीधे INADDR_ANY
से भरना कहते हैं, लेकिन getaddrinfo
प्रलेखन कहा गया है कि गुजर NULL
के रूप में पहले से ही nodename
INADDR_ANY
साथ पता भरना चाहिए, तो मुझे नहीं पता कि जब मैं इसे स्वचालित रूप से करता हूं तो मुझे पुरानी विधि का उपयोग क्यों करना चाहिए।
सर्वर भाग के लिए अपेक्षित कार्य करने के लिए (कनेक्शन स्वीकार करने में सक्षम होने के लिए) आपको 'श्रवण()' और 'स्वीकार()' पर कॉल जोड़ना होगा। आप अध्याय 9.15 और अध्याय 9.1 पर पढ़ना पसंद कर सकते हैं। – alk
@alk मैं स्पष्ट रूप से 'सुन' और 'स्वीकार' करने के लिए कॉल करता हूं (अन्यथा क्लाइंट कैसे काम करता है यदि क्लाइंट 'localhost'' server_name' के रूप में उपयोग करता है?)। मैं वैसे भी उन्हें प्रश्न में जोड़ दूंगा। – Bakuriu
क्या राउटर के पीछे सर्वर है? क्या आवश्यक बंदरगाह खोले या अग्रेषित किए गए हैं? – typ1232