C++ 套接字 - 发送 - 未收到数据

c++ socket - sendto - no data recieved

本文关键字:数据 发送 套接字 C++      更新时间:2023-10-16

>Visual Studio 2017 Community

C++ CLR 项目

应该将 UDP 数据报发送到组播地址。

我发送时没有错误。

--------------
MULTICAST
-------------------
'Project2.exe' (Win32): Loaded 'C:WindowsSysWOW64mswsock.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 nn", 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--------------nMULTICASTn-------------------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: %dnn"), 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:%snPORT:%dn-------------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 nn", 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 DONEn---------------------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(Sock, 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.

IP_ADD_MEMBERSHIP = 5

子网广播与多播不是一回事!

您已实现广播代码,但使用多播 IP 地址作为广播目标,这将不起作用。

在这种情况下,根本不要使用setsockopt(SOL_SOCKET, SO_BROADCAST)。 相反,您必须使用setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)加入多播组,然后才能向/从组发送/接收数据报。

阅读 MSDN 了解更多详细信息:

组播编程

原来...

setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)不是答案,数据是使用setsockopt(SOL_SOCKET, SO_BROADCAST)发送的。我测试并EJP指出。

egg on my face问题是我忘记了控制台中的数据始终为空,直到我解析缓冲区,然后数据存在。

谢谢大家。