Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как отправить одно сообщение на несколько машин с одной [D5, Win95/98, WinME, NT4, Win2k, WinXP]


Страницы:   1 2

serg128 ©   (2004-02-26 17:43:00) 

Как отправить одно сообщение на несколько машин с одной, используя сокеты.
Стандартным циклом оно не отправляется! Помогите плиз! Спасибо!
Если можно - кусочек кода!


Rouse_   (2004-02-27 09:32:00) [1]

Упс ссылки на FWUDPSocket убери - это лишнее...


Rouse_   (2004-02-27 09:29:00) [2]

Короче вот тебе пример UDP - Broadcast

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Winsock, StdCtrls, IdUDPServer, IdBaseComponent, IdComponent,
 IdUDPBase, IdUDPClient, IdSocketHandle, FWUDPSocket;

type
 TForm1 = class(TForm)
   Button1: TButton;
   IdUDPServer1: TIdUDPServer;
   Memo1: TMemo;
   FWUDPSocket1: TFWUDPSocket;
   procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
     ABinding: TIdSocketHandle);
   procedure Button1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

// Запуск сервера
procedure TForm1.FormCreate(Sender: TObject);
begin
 with IdUDPServer1 do
 begin
   BroadcastEnabled := True;
   DefaultPort := 1234;
   Active := True;
 end;
end;

// Создание сокета и отправка сообщения
procedure TForm1.Button1Click(Sender: TObject);
var
 FWSAData: TWSAData;
 FSockAddr: TSockAddrIn;
 FSocket: TSocket;
 Option: Boolean;
 Data: String;
begin
 WSAStartup($0101, FWSAData);
 FSocket := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 with FSockAddr do
 begin
   sin_addr.S_addr := INADDR_BROADCAST;
   sin_port := htons(1234);
   sin_family := AF_INET;
 end;
 Option := True;
 SetSockOpt(FSocket, SOL_SOCKET, SO_BROADCAST, PChar(@Option), SizeOf(Option));
 Data := 'This is test.';
 SendTo(FSocket, Data[1], Length(Data), 0, FSockAddr, SizeOf(FSockAddr));
 WSACleanup;
end;

// Принятие сообщения
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
 ABinding: TIdSocketHandle);
var
 S: TStringStream;
begin
 S := TStringStream.Create('');
 S.CopyFrom(AData, AData.Size);
 Memo1.Lines.Add(S.DataString);
 S.Free;
end;

end.


Желаю успехов


Digitman   (2004-02-27 09:08:00) [3]


> Verg ©   (27.02.04 08:36) [19]


все, я въехал)
недоразумение просто приключилось)


Verg   (2004-02-27 08:36:00) [4]


> [18] Digitman ©   (27.02.04 08:31)
>
> > Verg ©   (26.02.04 20:28) [17]
>
>
> >[17]   ????
>
> не понял ?)


Чего именно?


Digitman   (2004-02-27 08:31:00) [5]


> Verg ©   (26.02.04 20:28) [17]


>[17]   ????

не понял ?)


Verg   (2004-02-26 20:28:00) [6]

Так таймер там вообще PostMessage-заменитель. Раз уж схватился за TDataModule, то...


> так а мой пример разве плох? (Он кстати работает)


.......... Ну а что,

> Digitman ©  


...тебе еще не объяснил чем плох?

Еше раз "языки стесывать"?

Ну работает - и ладно, Бог с тобой.
Когда перестанет работать, может и вспомнишь то, что тебе говорили...


> serg128 ©   (26.02.04 17:43)
> Как отправить одно сообщение на несколько машин с одной,
> используя сокеты.
> Стандартным циклом оно не отправляется! Помогите плиз! Спасибо!


Типа показалось? :))

Да и не для тебя я это писал...., просто это уже оскомину набило - объяснять как работают с сокетом в неблокирующем, а особенно в асинхронном режиме.


serg128   (2004-02-26 19:55:00) [7]

тфу, гоню, согласен :))) так а мой пример разве плох? (Он кстати работает)


Verg   (2004-02-26 19:39:00) [8]


> [14] serg128 ©   (26.02.04 19:32)
> Была и такая идея, но таймер не катит, раз в 10 секунд -
> геморой. Но всё равно спасибо.


В 10 секунд :)))
А не миллисекунд ли, а ?
Ну ты даешь, программер...


serg128   (2004-02-26 19:32:00) [9]

Была и такая идея, но таймер не катит, раз в 10 секунд - геморой. Но всё равно спасибо.


Verg   (2004-02-26 19:19:00) [10]

Ух ты! Ну и дела...

Давай-ка экспромтом попробуем.
Пиво - "ПИТ", сокет  - неблокирующий,  язык - Делфи5 (не путать с BCB).

Погнали...

unit SendToAll;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 ScktComp, ExtCtrls, Db, DBTables, WinSock;

type
 TDataModule1 = class(TDataModule)
   ClientSocket: TClientSocket;
   Timer1: TTimer;
   Ods: TTable;
   procedure DataModule1Create(Sender: TObject);
   procedure DataModule1Destroy(Sender: TObject);
   procedure ClientSocketError(Sender: TObject; Socket: TCustomWinSocket;
     ErrorEvent: TErrorEvent; var ErrorCode: Integer);
   procedure Timer1Timer(Sender: TObject);
   procedure ClientSocketDisconnect(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocketWrite(Sender: TObject; Socket: TCustomWinSocket);
   procedure ClientSocketConnect(Sender: TObject;
     Socket: TCustomWinSocket);
 private
   { Private declarations }
 public
   { Public declarations }
   ErrList : TStringList;
   Delayed : string;
   InProgress : boolean;
   procedure Start;
   procedure Stop;
 end;

var
 DataModule1: TDataModule1;

implementation

{$R *.DFM}

procedure TDataModule1.DataModule1Create(Sender: TObject);
begin
 ErrList := TStringList.Create;
 Timer1.Enabled := false;
 Timer1.Interval := 10;
 Ods.Active := true;
end;

procedure TDataModule1.DataModule1Destroy(Sender: TObject);
begin
 Stop;
 ErrList.Free;
end;

procedure TDataModule1.ClientSocketError(Sender: TObject;
 Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
 var ErrorCode: Integer);
begin
 ErrList.Add('Can''t send message '+ods.FieldByName('TEX').AsString+' to '+
             ods.FieldByName('IP').AsString);
 ErrorCode := 0;
 if Socket<> nil then
   Socket.Close;
end;

procedure TDataModule1.Stop;
begin
 Timer1.Enabled := false;
 Ods.Active := false;
 if InProgress then
   ClientSocket.Socket.Close;
end;

procedure TDataModule1.Start;
begin
 Stop;
 Ods.Active := true;
 Ods.First;
 ErrList.Clear;
 Timer1.Enabled := true;
end;

procedure TDataModule1.Timer1Timer(Sender: TObject);
var ErrorCode : integer;
begin
 Timer1.Enabled       := false;
 ClientSocket.Port    := 6002;
 ClientSocket.Address := ods.FieldByName('IP').AsString;
 Delayed              :='';
 try
  ClientSocket.Active  := true;
  InProgress := true;
 except
  ClientSocketError(ClientSocket, nil, eeConnect, ErrorCode);
 end;
end;

procedure TDataModule1.ClientSocketDisconnect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
 if Ods.Active then
 begin
   Ods.Next;
   if not Ods.Eof then
     Timer1.Enabled:=true
   else
     //Все, оповещение закончено. Что тут делать надо еще придумывать.
 end;
end;

procedure TDataModule1.ClientSocketWrite(Sender: TObject;
 Socket: TCustomWinSocket);
var Sent,
   ErrorCode : integer;
begin
 if Delayed = '' then
   Delayed := ods.FieldByName('TEX').AsString;
 repeat
   if Delayed <>'' then
   begin
     Sent := Socket.SendBuf(Delayed[1], length(Delayed));
     if Sent = SOCKET_ERROR then
       Break;
     if Sent <= 0 then
     begin
       ClientSocketError(ClientSocket, Socket, eeSend, ErrorCode);
       break;
     end;
     Delete(Delayed, 1, Sent);
   end;
   if Delayed = '' then
   begin
     Socket.Close;
     break;
   end;
 until false;
end;

procedure TDataModule1.ClientSocketConnect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
 InProgress := false;
end;

end.


Ну что, "чего не хватает в этом супе"? :)


Digitman   (2004-02-26 18:47:00) [11]


> ClientSocket->Socket->SendText(ods->FieldByName("TEX")->AsString);


гдеанализ рез-та вызова функции ?


> ClientSocket->Active = false;


почему, не проанализировав результат передачи как вызова метода SendText, тут же закрываешь гнездо ?


>      ClientSocket->Close();


этозачем ?


Digitman   (2004-02-26 18:45:00) [12]


> Application->ProcessMessages();


это почему не в цикле ? ты вообще зачем эоту строчку поставил ? если осознанно, то в состоянии ли прокомментировать, чтоты ожидаешь в рез-те  ее исполнения ?


Digitman   (2004-02-26 18:44:00) [13]

ClientSocket->Active = true; // ну, предположим ,активировал ты здесь коннект... точнее, стартовал механизм коннекта ...
    ClientSocket->Open(); // а это зачем ??!


Digitman   (2004-02-26 18:42:00) [14]

миль пардон, в неблокирующем ... он у тебя. очевидно. используется ... заморочился уже я(


Digitman   (2004-02-26 18:40:00) [15]


> serg128 ©   (26.02.04 18:28) [7]


предлагаю ... почитать этот форум "Сети" ... где коллеги уже языки до костей сточили, объясняя денно и нощно по нннадцать раз на дню, что гнездо в блокирующем режиме должно программироваться в прикладной задаче с обязательным осознаннымипользованием практически всехсобытий, которые предоставляет компонент TClientSocket !

ты задавался себе хоть раз вопросом, а нахрена столько событий у этого компонента, когда и при каких условиях и в какой последовательности они возбуждаются ?


serg128   (2004-02-26 18:28:00) [16]

ну предложи что-то лучше, а не оххх((...


Digitman   (2004-02-26 18:26:00) [17]

оххх(( ...


serg128   (2004-02-26 18:06:00) [18]

ods->First();
  while(!ods->Eof)
  {

     TClientSocket *ClientSocket = new TClientSocket(this);
     ClientSocket->Port = 6002;
     ClientSocket->Address = ods->FieldByName("IP")->AsString;
     ClientSocket->Active = true;
     ClientSocket->Open();
     Application->ProcessMessages();
//      AnsiString tmps = ClientSocket->Address;
     ClientSocket->Socket->SendText(ods->FieldByName("TEX")->AsString);
     ClientSocket->Active = false;
     ClientSocket->Close();
     delete ClientSocket;

     ods->Next();
  }

// где ods->FieldByName("IP")->AsString - IP адрес
ods->FieldByName("Tex")->AsString - текст сообщения


Max003   (2004-02-26 18:03:00) [19]

ПОКАЖИ ЦИКЛ, ПОКАЖИ!!!


Chapha   (2004-02-26 17:58:00) [20]

Может BrouteCast?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо