2017-07-08 91 views
-1

的Visual Studio 2017年社區C++插座 - SENDTO - 沒有數據收到

C++ CLR項目

應該可以發送一個UDP數據報多播地址。

我發送沒有錯誤。

-------------- 
MULTICAST 
------------------- 
'Project2.exe' (Win32): Loaded 'C:\Windows\SysWOW64\mswsock.dll'. Symbols loaded. 

MULTICAST ---- 
IP:224.0.0.2 
PORT:7125 
------------- 

Sent: 13 


Sent: 13 


Sent: 13 

接收端收到這個輸入

{"socketId":0,"data":{},"remoteAddress":"192.168.0.80","remotePort":2535} 

下面是代碼

const char *msg = "1 2 3 4 5 6 7"; 


while (sending) { 

    //swprintf(str, L"\nMSG: \n%c ", channels); 
    //OutputDebugString(str); 

    // Send a message to the multicasting address. 
    int ret = sendto(Sock, msg, strlen(msg), 0, (struct sockaddr FAR *) &dest_sin, sizeof(dest_sin)); 

    swprintf(str, L"\nSent: %d \n\n", ret); 
    OutputDebugString(str); 

    if (ret == SOCKET_ERROR) 
    { 
     swprintf(str, L"\nsendto failed! Error: %d ", WSAGetLastError()); 
     OutputDebugString(str); 

     closesocket(Sock); 
     sending = false; 
    } 
    Sleep(66); 
} 

全部插座碼的發送部分,如果有幫助

// Sent message string 
TCHAR szError[100];    // Error message string 
SOCKET Sock = INVALID_SOCKET;  // Datagram window socket 

SOCKADDR_IN source_sin,   // Source socket address 
    dest_sin;    // Destination socket address 

WSADATA WSAData;     // Contains details of the 
            // Winsock implementation 


OutputDebugString(L"\n--------------\nMULTICAST\n-------------------\n"); 

// Initialize Winsock. 
if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0) 
{ 
    swprintf(str, TEXT("WSAStartup failed! Error: %d"), WSAGetLastError()); 
    OutputDebugString(str); 
    return FALSE; 
} 

// Create a datagram window socket, Sock. 
if ((Sock = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) 
{ 
    swprintf(str, TEXT("Allocating socket failed! Error: %d"), WSAGetLastError()); 
    OutputDebugString(str); 
    return FALSE; 
} 

// Fill out source socket's address information. 
source_sin.sin_family = AF_INET; 
source_sin.sin_port = htons(SOURCE_PORT); 
source_sin.sin_addr.s_addr = htonl(INADDR_ANY); 

// Associate the source socket's address with the socket, Sock. 
if (bind(Sock, 
    (struct sockaddr FAR *) &source_sin, 
    sizeof(source_sin)) == SOCKET_ERROR) 
{ 
    swprintf(str, TEXT("Binding socket failed! Error: %d"), WSAGetLastError()); 
    OutputDebugString(str); 
    closesocket(Sock); 
    return FALSE; 
} 

// Set the Time-to-Live of the multicast. 
int set_sock = setsockopt(Sock, SOL_SOCKET, SO_BROADCAST, (char FAR *)&iOptVal, sizeof(int)); 
if (set_sock == SOCKET_ERROR) 
{ 
    swprintf(str, TEXT("\n`setsockopt` failed! Error: %d\n\n"), WSAGetLastError()); 
    OutputDebugString(str); 
    closesocket(Sock); 
    return FALSE; 
} 


// Fill out the desination socket's address information. 
dest_sin.sin_family = AF_INET; 
dest_sin.sin_port = ntohs(mcast_port); 
dest_sin.sin_addr.s_addr = inet_addr(mcast_ip); 

swprintf(str, L"\nMULTICAST ----\nIP:%s\nPORT:%d\n-------------\n", mcast_ip, mcast_port); 
OutputDebugString(str); 


const char *msg = "1 2 3 4 5 6 7"; 


while (sending) { 

    //swprintf(str, L"\nMSG: \n%c ", channels); 
    //OutputDebugString(str); 

    // Send a message to the multicasting address. 
    int ret = sendto(Sock, msg, strlen(msg), 0, (struct sockaddr FAR *) &dest_sin, sizeof(dest_sin)); 

    swprintf(str, L"\nSent: %d \n\n", ret); 
    OutputDebugString(str); 

    if (ret == SOCKET_ERROR) 
    { 
     swprintf(str, L"\nsendto failed! Error: %d ", WSAGetLastError()); 
     OutputDebugString(str); 

     closesocket(Sock); 
     sending = false; 
    } 
    Sleep(66); 
} 


OutputDebugString(L"\n---------------------\nMULTICAST DONE\n---------------------\n"); 


if (!sending) { 
    // Disable sending on Sock before closing it. 
    shutdown(Sock, 0x01); 

    // Close Sock. 
    closesocket(Sock); 

    WSACleanup(); 
} 

從我已閱讀。

const char * msg

應該是正確的?

任何建議表示讚賞。

編輯:

作爲每Remy Lebeau

INT set_sock = setsockopt的(襪子,IPPROTO_IP,IP_ADD_MEMBERSHIP,(CHAR FAR *)& iOptVal,的sizeof(INT));

Error: 10042 -- An unknown, invalid or unsupported option or level was specified in a getsockopt or setsockopt call.

​​

回答

1

子網廣播方式是不一樣的東西多播!

您已經實現了廣播代碼,但是您使用多播IP地址作爲廣播目標,這將不起作用。

在這種情況下根本不要使用setsockopt(SOL_SOCKET, SO_BROADCAST)。相反,您必須先使用setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)才能加入多播組,然後才能向/從該組發送/接收數據報。

閱讀MSDN瞭解更多詳情:

Multicast Programming

+1

接收。您不必加入該組即可發送給它。 – EJP

+0

爲什麼選擇投票?這是一個問題....如果我知道答案,我不會在這裏。 –

+0

'IP_ADD_MEMBERSHIP'將一個指向['ip_mreq'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms738695.aspx)struct的指針作爲輸入,而不是'int'。閱讀文檔:[IPPROTO_IP套接字選項](https://msdn.microsoft.com/en-us/library/windows/desktop/ms738586.aspx) –

0

原來...

setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)不使用setsockopt(SOL_SOCKET, SO_BROADCAST)答案,發送數據。我測試過並且EJP指出。

問題egg on my face是我忘了控制檯中的數據總是空的,直到我解析緩衝區,然後數據存在。

謝謝大家。