Друзья, прошу помочь разобраться, что не так.
Есть код на Python 3.9, который через сокет успешно коннектится к мульткасту и слушает поток.
Пытаюсь сделать тоже на С\С++ - выдает ошибку при задании параметров IP_ADD_MEMBERSHIP, вроде делаю все по науке, как в руководстве про winsock написано. Чувствую, что не хватает знаний в Си.
Компилирую на mingw строкой gcc. Может тут как-то иначе порекомендуете?
Буду благодарна на комментарии и помощь.
Вот работающий код на питоне (ip и порты заменила на единички + добавила комментарии с моими вопросами):
Код:
import socket
import struct
from ipaddress import ip_address
group_address = "111.11.11.11"
local_address = "0.0.0.0"
port = 1111
#тут в строки байт переведены соответствующие переменные
#костыль, но питон для меня промежуточный работающий пример
#хочу научиться на Си/С++ работать с сокетами
sga = bytes(group_address)
sla = bytes(local_address)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0',port))
mreqn = struct.pack("=4s4s", sga, sla)
s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreqn)
while n<10:
message = s.recv(128)
print (message)
n = n + 1
s.setsockopt(socket.IPPROTO_IP, socket.IP_DROP_MEMBERSHIP, mreqn)
Вот аналог на С++
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <winsock.h>
#define SERVER "111.11.11.11"
#define BUFLEN 512
#define PORT 1111
int main(int argc, char **argv)
{
int nSock = 0;
int bytes_recv = 0;
char sRecvBuf[2048] = {0};
int index = 0;
int dRes = -1;
WSADATA w;
SOCKET sd;
struct sockaddr_in service;
if (WSAStartup(0x0101, &w) != 0)
{
printf("Could not open Windows connection.\n");
exit(0);
}
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == INVALID_SOCKET)
{
printf("Could not create socket.\n");
WSACleanup();
exit(0);
}
printf("Socket created.\n");
memset(&service,0,sizeof(service));
service.sin_family = AF_INET;
service.sin_port = htons(6016);
service.sin_addr.s_addr = htonl(INADDR_ANY);
int iResult = 0;
iResult = bind(sd, (SOCKADDR *) &service, sizeof (service));
if(iResult==SOCKET_ERROR)
{
printf("Cannot bind address to socket.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
else
printf("Binded. Error = %d\n", iResult);
//вот подозреваю, что тут ошибка где-то
//выдает ответ '-1'
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr("111.11.11.11");
mreq.imr_interface.s_addr = inet_addr("0.0.0.0");
iResult = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof(mreq));
printf("IP_ADD_MEMBERSHIP. Error = %d\n", iResult);
for(index = 0; index < 5; index++)
{
iResult = recv(sd, sRecvBuf, 512, 0);
if (iResult > 0)
printf("Bytes received: %d\n", iResult);
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
}
return 0;
}
-- 18.06.2021, 22:02 --друзья, у меня уже какая-то традиция, самой себе отвечать. не удалять же тему? В итоге надо было просто подключить дополнительно библиотеку Ws2tcpip, в которой эта самая структура
ip_mreq есть. Чувствую, надо подробную инструкцию писать, как же не тривиально это все на винде. Помогла статья вот эта:
https://habr.com/ru/post/141021/