c++ - Do I have to bind a UDP socket in my client program to receive data? (I always get WSAEINVAL) -


मैं एक यूडीपी सॉकेट ( AF_INET , SOCK_DGRAM , < कोड> IPPROTO_UDP ) के माध्यम से और इस सॉकेट पर recvfrom करने की कोशिश कर रहा है, लेकिन यह हमेशा -1 देता है और मुझे WSAEINVAL (10022) मिलता है। क्यों?

जब मैं बाँध () बंदरगाह, ऐसा नहीं होता है, लेकिन मैंने पढ़ा है कि यह क्लाइंट की गर्तिका को बांधने के लिए बहुत लंगड़ा है।

> मैं अपने सर्वर पर डेटा भेज रहा हूं, जो जवाब देता है, या कम से कम, करने की कोशिश करता है।

  इंक :: आंकड़े सिकुनेशन :: _ रिक्वेडाटा (एसकोडर * एडर, एसटीडी :: स्ट्रिंग और स्ट्रडाटा) {Int ret; // वापसी कोड int len; // डेटा से लंबाई int; // आकारफ (सॉकड्रर) चार * बफर; // डेटा को पकड़ेंगे c; // संदेश की लंबाई की लंबाई fromlen = sizeof (sockaddr); रेट = रिकवफॉर्म (एम_ इनसाकॉक, एंड सी, 1, 0, एडीआर, और सेलेन); यदि (ret! = 1) {#ifdef __MYDEBUG__ std :: stringstream ss; एसएस & lt; & lt; WSAGetLastError (); संदेश बॉक्स (NULL, ss.str ()। C_str (), "", MB_ICONERROR | MB_OK); #endif वापसी इंक :: ERECV; } ...  

यह एक काम उदाहरण है जिसे मैंने कुछ पल पहले लिखा था, और यह कॉल के बिना bind () में क्लाइंट में काम करता है:

  #pragma टिप्पणी (lib, "Ws2_32.lib") #define WIN32_LEAN_AND_MEAN #include & lt; WS2tcpip.h & gt; # शामिल & lt; Windows.h & gt; # शामिल करें & lt; iostream & gt; नेमस्पेस एसटीडी का उपयोग करना; Int main () {सॉकेट सोक; एड्रिनोफ़ो * पएडर; ऐड्रिन्फो संकेत; सोकदद एसएड्र; Int fromlen; Const char czPort [] = "12345"; Const char czAddy [] = "कुछ आईपी"; WSADATA wsa; अहस्ताक्षरित कम हमारे WESAVersion = MAKEWORD (2,2); चार बफर [22] = "टेस्टाटेस्टटीस्टटीईटी 5"; इंट रेट; // प्रारंभ WSA WSAStartup (usWSAVersion, और wsa); // गर्तिका सॉकेट = सॉकेट बनाएं (एएफआईएनईटीई, एसओसीकेडीएआरएएमएम, आईपीपीआरटीओ_यूपीपी); // होस्ट पता मेसेट (और amp; संकेत, 0, आकार (संकेत)) का समाधान करें; संकेत। Aai_family = AF_INET; संकेत। E_protocol = IPPROTO_UDP; संकेत। Ai_socktype = SOCK_DGRAM; अगर (getaddrinfo (czAddy, czPort, & amp; संकेत, & amp; pAddr)) {std :: cerr & lt; & lt; "पता हल नहीं किया जा सका ... \ n"; std :: cin.get (); वापसी 1; } // प्रारंभ ट्रांसमिशन जबकि (1) {ret = sendto (sock, बफर, आकार (बफर), 0, pAddr- & gt; ai_addr, pAddr- & gt; ai_addrlen); अगर (ret! = Sizeof (बफर)) {std :: cerr & lt; & lt; "डेटा नहीं भेजा जा सका \ n"; std :: cin.get (); वापसी 1; } Fromlen = sizeof (SOCKADDR); रेट = रिकवफ्रॉम (सॉक, बफर, साइज़फ (बफर), 0, एंड एसएड्र, और सेलेन); अगर (ret! = Sizeof (बफर)) {std :: cout & lt; & lt; "डेटा प्राप्त नहीं हो सका: त्रुटि:" & lt; & lt; WSAGetLastError () & lt; & lt; std :: endl; std :: cin.get (); वापसी 1; } बफर [रेट -1] = '\ 0'; Std :: cout & lt; & lt; "प्राप्त:" & lt; & lt; बफर & lt; & lt; std :: endl; } वापसी 0; }  

यूडीपी के साथ, आपको bind () क्लाइंट में गर्तिका क्योंकि यूडीपी कनेक्शन रहित है, इसलिए स्टैक के बारे में पता करने के लिए कोई अन्य रास्ता नहीं है कि किसी खास पोर्ट के लिए डेटाग्राम कैसे वितरित किया जाए।

यदि आप recvfrom () बिना बाँध () कर सकते हैं, तो आप अनिवार्य रूप से अपने प्रोग्राम को सभी यूडीपी डेटाग्राम भेजते हैं, जो स्टैक से पूछते हैं कंप्यूटर। चूंकि स्टैक डेटाग्राम को केवल एक प्रोग्राम तक पहुंचा देता है, यह डीएनएस, विंडोज़ नेटवर्क नेटवर्क, नेटवर्क टाइम सिंक को तोड़ सकता है ....

आपने नेट पर कहीं पढ़ा हो सकता है कि क्लाइंट में बाइंडिंग लंगड़ा है, लेकिन यह सलाह केवल टीसीपी कनेक्शन पर लागू होती है।


Comments

Popular posts from this blog

windows - Heroku throws SQLITE3 Read only exception -

lex - Building a lexical Analyzer in Java -

python - rename keys in a dictionary -