![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как отправить одно сообщение на несколько машин с одной [D5, Win95/98, WinME, NT4, Win2k, WinXP]
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?