2014-07-03 6 views
9

Vorrei inviare una stringa: "Jane Doe" all'intranet ip 192.168.0.4 sulla porta 9000 su UDP. L'ho fatto molte volte tramite UDP e TCP con Java, ma ora devo farlo con le librerie C++ standard e non riesco a trovare nessun campione solo per argomenti in cui le persone non riescono a farlo funzionare.Invio stringa su UDP in C++

So che devo codificare "Jane Doe" come matrice di byte, quindi basta aprire il socket, inserirlo in datagramma e inviarlo.

C++ non è la mia lingua madre e questa è una piccola parte del codice che non riesco a capire, ho scelto UDP perché è sempre molto più semplice di TCP.

+1

probabilmente sarei uso Boost ASIO. Se non potessi usare quello (per qualsiasi motivo), probabilmente utilizzerei la classe che ho postato su [una risposta su CodeReview] (http://codereview.stackexchange.com/a/46354/489). Così com'è, quel codice è specifico di Windows, ma quasi le uniche parti specifiche di Windows sono la classe 'socket_user' e la riga di' #pragma comment lib' (penso che quelle siano le uniche parti, ma non ho provato a essere sicuro). –

+0

@ Yoda si prega di scegliere una risposta –

risposta

10

Di seguito è riportato un esempio di codice Unix.

Se questa è la programmazione di Windows:

  • "calzino" dovrebbe essere di tipo SOCKET invece di int.
  • Uso closesocket invece di close
  • #include <winsock2.h> invece di tutte quelle intestazioni unix

#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 Dimostra il mio punto non c'è posto, almeno facile da trovare per ottenere campione e tecnica a cui si suppone di fare riferimento. – Yoda

+2

@black - un po 'nitpicky oggi no? Dovresti solo minimizzare una risposta se è completamente sbagliata o portare l'OP in un brutto posto. Non è richiesto il downvoting perché non ti piace lo stile di codifica. E se pensi di avere un * migliore * modo di rispondere alla domanda dell'OP, con tutti i mezzi posta una risposta. Potrei persino revocarlo da solo. Ho rimosso le intestazioni dalla risposta per mantenerla più concisa. – selbie

+0

@selbie E 'chiaramente affermato: "Se vedi informazioni sbagliate, vota." Onestamente, pensavo che avessi copiato il codice da qualche parte perché non viene fornito con alcuna documentazione. Inoltre, contiene un paio di errori (in effetti non funzionerà): 'sendto' richiede 6 argomenti, non 4. Infine, la conversione da stringa letterale a' char * 'è deprecata e non sicura. – edmz

10

Questo è molto facile da fare se si è disposti a utilizzare la libreria Boost.

Ecco il codice 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

Non dovrebbe essere il buffer di dimensione 9? Compreso '\ 0'? –

+0

se non si desidera avere valori letterali stringa, è sufficiente inserirli come byte: e l'indirizzo IPv4 richiede 4 byte con valori compresi tra 0-255 (inclusi).E tutti sappiamo 2^8 = 256 combinazioni possibili per 8 bit = 1 byte – dGRAMOP