Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.05.2009, 17:51   #1
svchaos
 
Регистрация: 30.05.2009
Сообщений: 9
Печаль WinSock, UDP, широковещание: Delphi (Pascal)

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

По указанной теме просмотрел материалы, но не смог понять, почему следующий код не работает:

Одиночный компьютер, запускаю сначала код программы:

Код:
program prExperimenter;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Winsock;

var WSAData:TWSAData;
    val,adrlen,erc:integer;
    s:TSocket;
    buf:string;
    WhoFrom,who,adr2:TSockAddr;
begin
  WSAStartUp($0202,WSAData);
  s:=Socket(AF_Inet,Sock_DGRAM,0);
//  val:=1;
//  SetSockOpt(s,SOL_Socket,SO_Broadcast,pchar(@val),SizeOf(integer));
  who.sin_family:=PF_Inet;
  who.sin_port:=HToNS(11111);
  who.sin_addr.S_addr:=INADDR_ANY;//Inet_Addr('127.0.0.1');
  FillChar(who.sin_zero,SizeOf(who.sin_zero),0);
  erc:=bind(s,who,sizeOf(who));
  writeln('error ',erc);
  WhoFrom.sin_family:=PF_Inet;
  WhoFrom.sin_port:=HToNS(5555);
  WhoFrom.sin_addr.S_addr:=Inet_Addr('127.0.0.1');
  erc:=Connect(s,WhoFrom,SizeOf(TSockAddr));
  writeln('error ',erc);
  writeln(WSAGetLastError);
  FillChar(WhoFrom.sin_zero,SizeOf(WhoFrom.sin_zero),0);
  setlength(buf,1024);
  adrlen:=SizeOf(TSockAddr);
  erc:=recvFrom(s,buf[1],1024,0,adr2,adrlen);
  writeln('error ',erc);
  writeln(WSAGetLastError);
  writeln(buf);
  readln;
  closeSocket(s);
end.
она, естественно, блокируется на recvFrom. Запускаю вторую программу, которая должна провести широковещательную передачу:

Код:
program prExperimenter2;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Winsock;

var WSAData:TWSAData;
    val,adrlen,erc:integer;
    s:TSocket;
    buf:string;
    whoTo,who,adr2:TSockAddr;
begin
  WSAStartUp($0202,WSAData);
  s:=Socket(AF_Inet,Sock_DGRAM,0);
  val:=1;
  SetSockOpt(s,SOL_Socket,SO_Broadcast,pchar(@val),SizeOf(integer));
  WhoTo.sin_family:=PF_Inet;
  WhoTo.sin_port:=HToNS(11111);//Кому
  WhoTo.sin_addr.S_addr:=HToNL(InAddr_Broadcast);//Inet_Addr('127.0.0.255');
  FillChar(WhoTo.sin_zero,SizeOf(WhoTo.sin_zero),0);
  who.sin_family:=PF_Inet;
  Who.sin_port:=HToNS(5555);//Кто
  Who.sin_addr.S_addr:=Inet_Addr('127.0.0.1');
  FillChar(Who.sin_zero,SizeOf(Who.sin_zero),0);
  erc:=bind(s,Who,sizeOf(Who));
  writeln('error ',erc);
  setlength(buf,1024);
  buf:='Kakaya-to stroka';
  adrlen:=SizeOf(TSockAddr);
  erc:=SendTo(s,buf[1],length(buf),0,WhoTo,adrlen);
  writeln('Sent symbols ',erc);
  writeln(WSAGetLastError);
  writeln('Sent: '+buf);
  readln;
  closeSocket(s);
  WSACleanUp;
end.
И ничегошеньки не происходит... Программки выдают себе нули: ошибок вроде нет, а prExperimenter ничего не слышит.

Ткните пожалуйста носом туда, где наврал...
svchaos вне форума Ответить с цитированием
Старый 30.05.2009, 19:32   #2
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

В первой проге в recvfrom надо не adr2, а who.
А connect можно вообще убрать. Для udp сокетов сonnect только устанавливает фильтр, в таком случае можно использовать recv. А при использовании recvfrom он ничем не поможет.
Somebody вне форума Ответить с цитированием
Старый 30.05.2009, 19:47   #3
svchaos
 
Регистрация: 30.05.2009
Сообщений: 9
По умолчанию

Попробовал, на удачу. Не помогло: recvFrom в adr2 кидает только адрес полученной датаграммы, а датаграммы-то и нету... А Connect здесь - бесполезный придаток, вы правы.
svchaos вне форума Ответить с цитированием
Старый 30.05.2009, 19:50   #4
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

recvfrom на то и from, что принимает только с заданного адреса. Проверял у себя - после исправления всё работает.
Somebody вне форума Ответить с цитированием
Старый 30.05.2009, 19:58   #5
svchaos
 
Регистрация: 30.05.2009
Сообщений: 9
По умолчанию

И я проверял у себя - молчит RecvFrom c предлагаемыми измениями.
Может быть, я что-то путаю, но RecvFrom у меня в другой программе принимал датаграммы с любого адреса, а отличался от Recv только тем, что давал их адрес.
svchaos вне форума Ответить с цитированием
Старый 30.05.2009, 20:19   #6
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Ну да, я перепутал, действительно, recvfrom сохраняет туда адрес.
Перепроверил: у меня и до исправления работает, и после. Виндовсовский брандмауэр или другой какой фаервол не блокирует?

Последний раз редактировалось Somebody; 30.05.2009 в 20:22.
Somebody вне форума Ответить с цитированием
Старый 30.05.2009, 23:23   #7
svchaos
 
Регистрация: 30.05.2009
Сообщений: 9
По умолчанию

Похоже, у меня не программа барахлит, а система чего-то не разрешает. Какие-то привилегии, например, не разрешены - не знаю. У кого бы спросить?
svchaos вне форума Ответить с цитированием
Старый 31.05.2009, 16:18   #8
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Вот сейчас вспомнил, что у меня такое тоже было. Когда сеть была отключена, прога не могла найти свой сервер broadcastом, когда включил роутер, стало всё нормально. То есть без сети это почему-то не работает.
Somebody вне форума Ответить с цитированием
Старый 01.06.2009, 20:41   #9
svchaos
 
Регистрация: 30.05.2009
Сообщений: 9
По умолчанию

А как сделать, чтобы заработало? Мне в другом месте советовали создать виртуальную сеть, но как ее сделать, особенно на преподавательском компе, я представления не имею. А хотелось бы...
svchaos вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
UDP сниффер XAOC-forever Работа с сетью в Delphi 3 11.07.2011 22:14
UDP и данные Shouldercannon Работа с сетью в Delphi 4 30.07.2008 09:12