2014-07-03 23 views
9

Ich möchte eine Zeichenfolge senden: "Jane Doe" zu Intranet IP 192.168.0.4 zu Port 9000 über UDP. Ich habe das schon oft über UDP und TCP per Java gemacht, aber jetzt muss ich es mit Standard-C++ - Bibliotheken machen und ich kann keine Beispiele finden, nur Themen, bei denen die Leute es einfach nicht funktionieren lassen können.Senden von Zeichenfolge über UDP in C++

Ich weiß, dass ich "Jane Doe" als Array von Bytes codieren muss dann einfach öffnen Sie den Sockel, packen Sie es in Datagramm und senden Sie es.

C++ ist nicht meine erste Sprache und das ist kleiner Teil des Codes, den ich nicht herausfinden kann, habe ich UDP gewählt, weil es immer viel einfacher als TCP ist.

+1

ich wahrscheinlich Erhöhung ASIO verwenden würde. Wenn ich das (aus welchen Gründen auch immer) nicht verwenden könnte, würde ich wahrscheinlich die Klasse verwenden, die ich in [eine Antwort auf CodeReview] veröffentlicht habe (http://codereview.stackexchange.com/a/46354/489). Wie es aussieht, ist dieser Code Windows-spezifisch, aber fast die einzigen Windows-spezifischen Teile sind die 'socket_user'-Klasse und die '#pragma comment lib'-Zeile (ich denke, das sind die einzigen Teile, aber ich habe nicht getestet sicher sein). –

+0

@Yoda bitte wählen Sie eine Antwort –

Antwort

10

Unten finden Sie einige Beispiele für Unix-Code.

Wenn die Windows-Programmierung:

  • "Socke" vom Typ sein sollte SOCKET statt int.
  • Verwenden closesocket statt close
  • #include <winsock2.h> statt all den Unix-Header

#include <sys/types.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <netdb.h> 
#include <memory.h> 
#include <ifaddrs.h> 
#include <net/if.h> 
#include <errno.h> 
#include <stdlib.h> 
#include <iostream> 


int resolvehelper(const char* hostname, int family, const char* service, sockaddr_storage* pAddr) 
{ 
    int result; 
    addrinfo* result_list = NULL; 
    addrinfo hints = {}; 
    hints.ai_family = family; 
    hints.ai_socktype = SOCK_DGRAM; // without this flag, getaddrinfo will return 3x the number of addresses (one for each socket type). 
    result = getaddrinfo(hostname, service, &hints, &result_list); 
    if (result == 0) 
    { 
     //ASSERT(result_list->ai_addrlen <= sizeof(sockaddr_in)); 
     memcpy(pAddr, result_list->ai_addr, result_list->ai_addrlen); 
     freeaddrinfo(result_list); 
    } 

    return result; 
} 


int main() 
{ 
    int result = 0; 
    int sock = socket(AF_INET, SOCK_DGRAM, 0); 

    char szIP[100]; 

    sockaddr_in addrListen = {}; // zero-int, sin_port is 0, which picks a random port for bind. 
    addrListen.sin_family = AF_INET; 
    result = bind(sock, (sockaddr*)&addrListen, sizeof(addrListen)); 
    if (result == -1) 
    { 
     int lasterror = errno; 
     std::cout << "error: " << lasterror; 
     exit(1); 
    } 


    sockaddr_storage addrDest = {}; 
    result = resolvehelper("192.168.0.4", AF_INET, "9000", &addrDest); 
    if (result != 0) 
    { 
     int lasterror = errno; 
     std::cout << "error: " << lasterror; 
     exit(1); 
    } 

    const char* msg = "Jane Doe"; 
    size_t msg_length = strlen(msg); 

    result = sendto(sock, msg, msg_length, 0, (sockaddr*)&addrDest, sizeof(addrDest)); 

    std::cout << result << " bytes sent" << std::endl; 

    return 0; 

} 
+0

@black Es beweist meinen Punkt, es gibt keinen Platz, zumindest leicht zu finden, um Probe und Technik zu erhalten, auf die man verweisen soll. – Yoda

+2

@black - ein wenig pingelig heute sind wir nicht? Sie sollten nur eine Antwort ablehnen, wenn sie völlig falsch ist oder das OP an einen schlechten Ort führen würde. Downvoting, weil Sie den Codierungsstil nicht mögen, ist nicht erforderlich. Und wenn Sie denken, dass Sie eine * bessere * Möglichkeit haben, die Frage des OP zu beantworten, schreiben Sie auf jeden Fall eine Antwort. Ich könnte es sogar selbst aufwerten. Ich habe die Header aus der Antwort entfernt, um sie übersichtlicher zu halten. – selbie

+0

@selbie Es wird deutlich gesagt: 'Wenn Sie Fehlinformationen sehen, stimmen Sie ab. Ehrlich gesagt dachte ich, Sie hätten den Code irgendwo kopiert, weil er keine Dokumentation enthält. Außerdem enthält es ein paar Fehler (in der Tat wird es nicht funktionieren): 'sendto' benötigt 6 Argumente, nicht 4. Schließlich ist die Umwandlung von String-Literal in' char * 'veraltet und unsicher. – edmz

10

Dies ist sehr einfach zu tun, wenn Sie die Boost-Bibliothek bereit zu verwenden sind.

Hier ist der Code Snippit

#include "boost/asio.hpp" 
using namespace boost::asio; 

... 

io_service io_service; 
ip::udp::socket socket(io_service); 
ip::udp::endpoint remote_endpoint; 

socket.open(ip::udp::v4()); 

remote_endpoint = ip::udp::endpoint(ip::address::from_string("192.168.0.4"), 9000); 

boost::system::error_code err; 
socket.send_to(buffer("Jane Doe", 8), remote_endpoint, 0, err); 

socket.close(); 
+0

Sollte der Puffer nicht die Größe 9 haben? Einschließlich '\ 0'? –

+0

Wenn Sie keine Zeichenfolgenliterale haben möchten, können Sie einfach als Bytes einfügen: und IPv4-Adresse dauert 4 Bytes mit Werten zwischen 0-255 (einschließlich).Und wir alle kennen 2^8 = 256 mögliche Kombinationen für 8 Bits = 1 Byte – dGRAMOP