I am trying to listen a socket using multicast but it seems that am not using the setsockopt
function well. I have been searching the meaning of the error code 10042 and I have found https://learn.microsoft.com/windows/win32/winsock/windows-sockets-error-codes-2 but I don't understand the explanation.
Here it is my function where I create a socket to listen a port inside a multicast group:
/* Includes */
#include <windows.h>
#include <winsock.h>
#include <iostream>
#include <cstdlib>
#pragma comment (lib, "Ws2_32.lib")
/* Defines */
#define BUFLEN 1024
#define MULTICAST_GROUP "225.30.8.1"
#define LOCAL_IP "192.168.6.200"
#define DEFAULT_FTI_PORT 8600
/* Structs */
typedef struct {
uint32_t receive_data[BUFLEN]; // receive data
}comm_data_t;
typedef struct {
SOCKET sockfd; // RX socket ID
int long_dir; // size of address
struct sockaddr_in socket_addr; // client socket struct
struct sockaddr_in socket_sender; // sender socket struct
comm_data_t data; // data struct
}socket_t;
socket_t socket_info;
/* Returns 1 if succesfull, 0 otherwise */
uint8_t createSocket(void)
{
WSADATA wsaData;
struct ip_mreq mreq; // multicast
int iResult;
cout << "IP: " << LOCAL_IP << endl;
cout << "MULTICAST GROUP: " << MULTICAST_GROUP << endl;
cout << "PORT: " << DEFAULT_FTI_PORT << endl << endl;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("[SOCKET] WSAStartup failed with error: %d\n", iResult);
return 0;
}
memset(&socket_info.socket_addr, 0, sizeof(socket_info.socket_addr));
socket_info.socket_addr.sin_family = AF_INET;
socket_info.socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);
socket_info.socket_addr.sin_port = htons(DEFAULT_FTI_PORT);
socket_info.long_dir = sizeof(socket_info.socket_sender);
// Create a new socket to make a client connection.
if ((socket_info.sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
printf("[SOCKET] socket() failed! Error code: %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
else
printf("[SOCKET] socket() is OK!\n");
if (bind(socket_info.sockfd, (struct sockaddr*) &socket_info.socket_addr, sizeof(socket_info.socket_addr)) < 0)
{
printf("[SOCKET] bind() failed! Error code: %ld\n", WSAGetLastError());
return 0;
}
else
printf("[SOCKET] bind() is OK!\n");
// Set multicast option
mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP);
mreq.imr_interface.s_addr = inet_addr(LOCAL_IP);
if ( (setsockopt(socket_info.sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof(mreq))) < 0)
{
printf("[SOCKET] setsockopt() failed! Error code: %ld\n", WSAGetLastError());
return 0;
}
else
printf("[SOCKET] setsockopt() is OK!\n");
return 1;
}
And then I have another function where I read the received data:
/* Returns number of bytes received */
uint8_t readFromSocket(void)
{
int32_t BytesReceived = 0;
/* RECEIVE DATA */
BytesReceived = recvfrom(socket_info.sockfd, (char*) &socket_info.data.receive_data,
BUFLEN, 0,
(struct sockaddr*) &socket_info.socket_sender,
&socket_info.long_dir);
if (BytesReceived < 0)
{
printf("[SOCKET] recvfrom() error %ld.\n", WSAGetLastError());
return 0;
}
else
return BytesReceived ;
}
It seems that I am not able to join myself to the multicast group, but I don't know where I am failing.
I am using UDP protocol, so if I change the parameter of setsockopt
IPPROTO_IP to IPPROTO_UDP, I get the error code 10022.
What do these errors mean and how can I do it correctly?
CodePudding user response:
You're using an old set of include files. Instead of this:
#include <windows.h>
#include <winsock.h>
Use this:
#include <winsock2.h>
#include <ws2tcpip.h>
And it should work as expected.
CodePudding user response:
I have found the solution by my own.
I have being using another native .lib from Windows.
Before, on my header file I had:
#pragma comment (lib, "Ws2_32.lib")
But now, I use another .lib. This is the library that I am using right now and works for me:
#pragma comment (lib, "wsock32.lib")
I suppose that is a matter of distribution of my OS.
Thank you very much anyway for your comments.