2009-03-24 2 views
15

Я хочу создать Winsock UDP-сокет, который отправляет данные только клиенту. Я хочу, чтобы ядро ​​выбрало доступный порт для меня. С другой стороны, я хочу указать, какой локальный IP использовать, поскольку я запускаю несколько nics.Как установить Winsock UDP-сокет?

Я пробовал расчесывать лабиринт опций сокета, а также привязывать порт к адресу сокета, установленному в 0, безрезультатно.

Мой код находится в Win32 C++.

ответ

21

Пожалуйста, простите за отсутствие проверки ошибок:

char pkt[...]; 
size_t pkt_length = ...; 
sockaddr_in dest; 
sockaddr_in local; 
WSAData data; 
WSAStartup(MAKEWORD(2, 2), &data); 

local.sin_family = AF_INET; 
local.sin_addr.s_addr = inet_addr(<source IP address>); 
local.sin_port = 0; // choose any 

dest.sin_family = AF_INET; 
dest.sin_addr.s_addr = inet_addr(<destination IP address>); 
dest.sin_port = htons(<destination port number>); 

// create the socket 
SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
// bind to the local address 
bind(s, (sockaddr *)&local, sizeof(local)); 
// send the pkt 
int ret = sendto(s, pkt, pkt_length, 0, (sockaddr *)&dest, sizeof(dest)); 
-1

Не прямое «HowTo», но я использовал библиотеку с открытым исходным кодом под названием «ACE (адаптивная среда связи) для всех моих программ сокетов TCP и UDP и считал ее очень полезной и мощной. Требуется« программное обеспечение pattens «подход к предоставлению строительных блоков для решения вашей конкретной проблемы. Я смог использовать их инкапсуляцию UDP для подключения к данному порту и отправки ответов на свободный порт, выбранный системой. В качестве альтернативы вы можете указать обратный порт, если хотите . ACE доступен здесь: ACE Homepage

-1

Когда вы говорите: «Я хочу указать, какой локальный IP-адрес использовать, поскольку я запускаю несколько nics», вы имеете в виду, что вы хотите указать IP-адрес, или вы хотите указать nic и использовать связанный адрес ip?

Если вы пытаетесь указать nic, this question должен быть уместным.

1

Ответ Graeme Perrow больше не работает, потому что inet_addr устарел. Вместо этого используйте inet_pton:

#include <string> 
#include <WinSock2.h> 
#include <Ws2tcpip.h> 

#pragma comment(lib, "ws2_32.lib") 
using namespace std; 

int main() { 
    const char* pkt = "Message to be sent"; 
    const char* srcIP = < source IP address >; 
    const char* destIP = < destination IP address >; 
    sockaddr_in dest; 
    sockaddr_in local; 
    WSAData data; 
    WSAStartup(MAKEWORD(2, 2), &data); 
    ULONG* srcAddr = new ULONG; 
    ULONG* destAddr = new ULONG; 

    local.sin_family = AF_INET; 
    inet_pton(AF_INET, srcIP, srcAddr); 
    local.sin_addr.s_addr = *srcAddr; 
    local.sin_port = htons(0); 

    dest.sin_family = AF_INET; 
    inet_pton(AF_INET, destIP, destAddr); 
    dest.sin_addr.s_addr = *destAddr; 
    dest.sin_port = htons(< destination port number >); 

    SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    bind(s, (sockaddr *)&local, sizeof(local)); 

    sendto(s, pkt, strlen(pkt), 0, (sockaddr *)&dest, sizeof(dest)); 

    delete srcAddr; 
    delete destAddr; 

    return 0; 
}