Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2006.10.22;
Скачать: [xml.tar.bz2];

Вниз

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

 
борменталь   (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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.039 c
15-1159879783
vitv
2006-10-03 16:49
2006.10.22
API Висты


1-1157801018
guav
2006-09-09 15:23
2006.10.22
Прозрачный ТМемо


15-1159459450
Footballer
2006-09-28 20:04
2006.10.22
Siemens C65


15-1159365028
Piter
2006-09-27 17:50
2006.10.22
Подскажите простой и надежный движок форума


2-1160140411
Xtreme
2006-10-06 17:13
2006.10.22
Delphi.Begin3





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский