2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Сокеты на python и на C++
Сообщение18.06.2021, 21:27 
Друзья, прошу помочь разобраться, что не так.
Есть код на 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/

 
 
 [ 1 сообщение ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group