2014-07-03 14 views
9

Chciałbym wysłać ciąg: "Jane Doe" do intranetu ip 192.168.0.4 do portu 9000 przez UDP. Robiłem to wiele razy przez UDP i TCP przez Javę, ale teraz muszę to zrobić ze standardowymi bibliotekami C++ i nie mogę znaleźć żadnych próbek tylko tematów, w których ludzie po prostu nie mogą tego zrobić.Wysyłanie ciągu znaków przez UDP w C++

Wiem, że muszę zakodować "Jane Doe" jako tablicę bajtów, a następnie wystarczy otworzyć gniazdo, spakować je w datagramie i wysłać.

C++ nie jest moim pierwszym językiem i jest to niewielka część kodu, którego nie mogę wymyślić, wybrałem UDP, ponieważ zawsze jest znacznie prostsze niż TCP.

+1

bym prawdopodobnie używać Zwiększ ASIO. Gdybym nie mógł tego użyć (z jakiegokolwiek powodu), prawdopodobnie użyłbym klasy, którą opublikowałem w [odpowiedź na CodeReview] (http://codereview.stackexchange.com/a/46354/489). W obecnej postaci kod ten jest specyficzny dla systemu Windows, ale prawie jedynymi częściami specyficznymi dla systemu Windows są klasa 'socket_user' i linia' #pragma comment lib' (uważam, że są to jedyne części, ale nie testowałem być pewnym). –

+0

@Yoda wybierz odpowiedź –

Odpowiedz

10

Poniżej znajduje się przykładowy kod Uniksa.

Jeśli jest to programowanie Windows:

  • "skarpeta" powinny być typu SOCKET zamiast int.
  • Zastosowanie closesocket zamiast close
  • #include <winsock2.h> zamiast tych wszystkich nagłówkach uniksowych

#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 Potwierdzam, że nie ma miejsca, przynajmniej łatwe do znalezienia, aby uzyskać próbkę i technikę, do której należy się odwoływać. – Yoda

+2

@ black - trochę dziadka dzisiaj, prawda? Powinieneś odrzucić odpowiedź tylko wtedy, gdy jest ona całkowicie błędna lub doprowadzi OP do złego miejsca. Nie wymaga to rezygnacji, ponieważ nie podoba ci się styl kodowania. A jeśli uważasz, że masz * lepszy * sposób, aby odpowiedzieć na pytanie OP, to z całą pewnością opublikuj odpowiedź. Mogę nawet zrobić to samo. Usunąłem nagłówki z odpowiedzi, aby były bardziej zwięzłe. – selbie

+0

@selbie Wyraźnie stwierdzono: "Jeśli widzisz dezinformację, zagłosuj na nią. Szczerze mówiąc, myślałem, że skopiowałeś kod skądś, bo nie ma żadnej dokumentacji. Co więcej, zawiera kilka błędów (w rzeczywistości nie zadziała): 'sendto' wymaga 6 argumentów, nie 4. Wreszcie, konwersja z literału ciągu na" char * "jest przestarzała i nie jest bezpieczna. – edmz

10

Jest to bardzo proste do zrobienia, jeśli są chętni do korzystania z biblioteki Boost.

Oto kod 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

Czy bufor nie powinien mieć rozmiaru 9? W tym '\ 0'? –

+0

jeśli nie chcesz mieć literałów łańcuchowych, możesz po prostu wstawić jako bajty: a adres IPv4 zajmuje 4 bajty o wartościach od 0-255 (włącznie).I wszyscy wiemy 2^8 = 256 możliwych kombinacji dla 8 bitów = 1 bajtu – dGRAMOP