Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.22;
Скачать: CL | DM;

Вниз

широковещательные сообщения   Найти похожие ветки 

 
борменталь   (2006-05-25 13:52) [0]

Здравствуйте!

В сетке используется чат. Легко пробивается с другие сегменты. Если открыть UDP-сокет, то его сообщения перехватываются. То есть (вероятно) используется UDP broadcast. Также сообщения ловятся приемником, забинденным на групповой multicast-адрес, то есть это не юникаст...

Пытаюсь сделать аналогично, но не получается. В пределах своего сегмента сообщения уходят и принимаются, за пределами сегмента - тишина. Пробовал и multicast, и broadcast - результат тот же :(

Но чат-то работает! (FChat, кстати).

посмотрите, пожалуйста, мой код - что я мог пропустить?

multicast:
var
 h: TSocket;
 MulticastTTL: DWORD;
 multicastAddr: sockaddr_in;
 sendString: array[0..512] of char;
 multicastRequest: ip_mreq;
begin
 MulticastTTL:= StrToInt(edit4.Text);
 StrPCopy(sendString, Edit1.Text);
 sendString[Length(edit1.text)]:= #0;
 h:= socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
 if h<0 then DieWithError("socket");

// это я от бессилия... не помогло
//  if setsockopt(h, IPPROTO_IP, IP_TTL, @multicastTTL,
//    sizeof(MulticastTTL)) < 0 then
//      DieWithError("setsockopt() failed");

 if setsockopt(h, IPPROTO_IP, IP_MULTICAST_TTL, @multicastTTL,
   sizeof(multicastTTL))<0 then DieWithError("TTL");

// вообще тоже не нужно. Но мешать не может (если тут нет ошибки)
 FillChar(multicastAddr, sizeof(multicastAddr), 0);
 multicastRequest.imr_multiaddr.s_addr := inet_addr(pchar(edit2.text));
 multicastRequest.imr_interface.s_addr := htonl(INADDR_ANY);

 if setsockopt(h, IPPROTO_IP, IP_ADD_MEMBERSHIP, @multicastRequest,
   sizeof(multicastRequest)) < 0 then
     DieWithError("setsockopt() failed");

 getsockopt(h, IPPROTO_IP, IP_ADD_MEMBERSHIP, @multicastRequest,
   sizeof(multicastRequest)) < 0 then
     DieWithError("setsockopt() failed");

 multicastAddr.sin_family:= AF_INET;
 multicastAddr.sin_addr.S_addr:= inet_addr(pchar(edit2.text));
 multicastAddr.sin_port:= htons(strtoint(edit3.text));
 if sendto(h, sendString, StrLen(sendString)+1, 0, multicastAddr, sizeof(multicastAddr)) <> StrLen(sendString)+1 then
     DieWithError("sendto() sent a different number of bytes than expected");

 closesocket(h);
end;


код сервера (приемника)

var
 MulticastTTL: DWORD;
 multicastAddr: sockaddr_in;
 multicastRequest: ip_mreq;
 recvStringLen, xx: Integer;
 recvString: array[0..512] of Char;
begin
 MulticastTTL:= 128; // это не нужно, но мешать не должно
 h:= socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
 if h<0 then DieWithError("socket");

 FillChar(multicastAddr, sizeof(multicastAddr), 0);
 multicastAddr.sin_family:= AF_INET;
 multicastAddr.sin_addr.S_addr:= htonl(INADDR_ANY);
 multicastAddr.sin_port:= htons(StrToInt(edit2.text));

// это не нужно, но мешать не должно
 if setsockopt(h, IPPROTO_IP, IP_MULTICAST_TTL, @multicastTTL,
   sizeof(multicastTTL))<0 then DieWithError("TTL");

 if bind(h, multicastAddr, sizeof(multicastAddr)) < 0 then
   DieWithError("bind() failed");

 multicastRequest.imr_multiaddr.s_addr := inet_addr(pchar(edit1.text)); // групповой адрес
 multicastRequest.imr_interface.s_addr := htonl(INADDR_ANY);

 if setsockopt(h, IPPROTO_IP, IP_ADD_MEMBERSHIP, @multicastRequest,
   sizeof(multicastRequest)) < 0 then
     DieWithError("setsockopt() failed");

 WSAAsyncSelect(h, Form1.Handle, WM_User, FD_Read);

затем в обработчике события FD_Read:
procedure TForm1.OnSocketRead(var M: TMessage);
var
 MulticastTTL: byte;
 multicastAddr: sockaddr_in;
 multicastRequest: ip_mreq;
 recvStringLen, xx: Integer;
 recvString: array[0..512] of Char;
begin
 FillChar(multicastAddr, sizeof(multicastAddr), 0);
 recvStringLen:= SizeOf(multicastAddr);
 xx := recvfrom(h, recvString, MAXRECVSTRING, 0, multicastAddr, recvStringLen);
 if  xx>0 then begin
   recvString[xx] := #0;
   Memo1.Lines.Add(recvString);
 end;
end;


внутри сегмента все работает, так как я хочу.

UDP Broadcast:
приемник стандартный, ничего особенного. Можно пользоваться даже приемником из мультикаста.

клиент:

procedure TForm1.Button1Click(Sender: TObject);
var
 h: TSocket;
 MulticastTTL: DWORD;
 Addr: sockaddr_in;
 sendString: array[0..512] of char;
 len: Integer;
 yes: Integer;
begin
 MulticastTTL:= 255; // пробовал и 5, и 64, и 128, и др. значения
 sendString:= "Cisco unified datagram report"#0;

 h:= socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 if h<0 then DieWithError("socket");

 yes:= 1;
 if setsockopt(h, SOL_SOCKET, SO_BROADCAST, @yes,
   sizeof(yes)) < 0 then
     DieWithError("setsockopt() failed");

 if setsockopt(h, IPPROTO_IP, IP_TTL, @multicastTTL,
   sizeof(MulticastTTL)) < 0 then
     DieWithError("setsockopt() failed");

 Addr.sin_family:= AF_INET;
 Addr.sin_addr.S_addr:= inet_addr("255.255.255.255");
//  Addr.sin_addr.S_addr:= inet_addr("10.255.255.255"); // как вариант
 Addr.sin_port:= htons(9999); // на этом порту работает FChat
 len:= sendto(h, sendString, StrLen(sendString)+1, 0, Addr, sizeof(Addr));
 if len <> StrLen(sendString)+1 then
     DieWithError("sendto() sent a different number of bytes than expected");
 closesocket(h);
end;


В чем я неправ?

З.Ы. может ФЧат вообще на raw-сокетах работает? такое возможно? (сообщения приходят буквально на каждый хост)


 
Сергей М. ©   (2006-05-25 14:08) [1]

Какой, нафих, в UDP "мультикаст" ?!


 
борменталь   (2006-05-25 14:13) [2]

а что не так?
сокет SOCK_DGRAM значит UDP.
но можно сказать и IP multicast, я не против


 
Сергей М. ©   (2006-05-25 14:37) [3]

multicast имеет отношение к TCP, но не к UDP.


 
борменталь   (2006-05-25 14:46) [4]


> Сергей М. ©   (25.05.06 14:37) [3]
> multicast имеет отношение к TCP, но не к UDP.

да мне все равно. Ты по существу скажи что-нибудь, пожалуйста!


 
Сергей М. ©   (2006-05-25 15:06) [5]

В чем заключается "существо" ?

ТЗ - на всеобщее обозрение...


 
борменталь   (2006-05-25 15:24) [6]

как правильно осуществлять многоадресную передачу (multicast или broadcast) в многосегментных сетях?

только нужен код. Можно прокомментировать мой код, можно выложить чужой. Лишь бы разобраться, где я ошибся.


 
Сергей М. ©   (2006-05-25 15:33) [7]

А ты не задавался ли себе вопросом, почему бродкаст-сообщение по адресу 255.255.255.255 не получает никто за пределами сети твоего провайдера ?


 
борменталь   (2006-05-25 15:37) [8]

чорт... ты не задавался вопросом, почему FChat сообщения передает?
умный нашелся


 
Сергей М. ©   (2006-05-25 16:04) [9]


> борменталь   (25.05.06 15:37) [8]


> почему FChat сообщения передает?


По кочану.

FChat работает в пределах сегментов подсети твоего провайдера.
Иначе и быть не может, если провайдер при мозгах.


> умный нашелся


Дуй книжки читать.


 
isasa ©   (2006-05-25 17:30) [10]

Из-за чего ругань пошла!

myMulticast:=(myIP and myIPMask) and $FFFFFFFF;

255.255.255.255 это сильно круто. :)


 
Bormental   (2006-05-25 17:32) [11]

Книжки читал. Потому и обращаюсь сюда. Говорю же, почему у меня не получается как у фчата? Код мой покритикуй, скажи чего в нем не хватает


 
isasa ©   (2006-05-25 17:35) [12]

Сорри, тоже погорячился.

myMulticast:=(myIP or (not myIPMask);


 
Bormental   (2006-05-25 17:38) [13]

Isasa, ты спаситель, я уж уходить хотел. Проверю, сообщу результат.



Страницы: 1 вся ветка

Текущий архив: 2006.10.22;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.029 c
2-1159772470
ttt_111
2006-10-02 11:01
2006.10.22
Работа с файлами.


2-1160097054
lobach
2006-10-06 05:10
2006.10.22
Ресурсы...


2-1160311802
alexa14
2006-10-08 16:50
2006.10.22
Динамическое создание popupmenu


2-1160038651
Neket
2006-10-05 12:57
2006.10.22
Проблема с динамическими массивами


15-1159505220
boriskb
2006-09-29 08:47
2006.10.22
Энциклопедия целочисленных последовательностей.