Форум: "Сети";
Текущий архив: 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