Форум: "Сети";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
ВнизКак отправить одно сообщение на несколько машин с одной Найти похожие ветки
← →
serg128 © (2004-02-26 17:43) [0]Как отправить одно сообщение на несколько машин с одной, используя сокеты.
Стандартным циклом оно не отправляется! Помогите плиз! Спасибо!
Если можно - кусочек кода!
← →
Max003 (2004-02-26 17:54) [1]Хм... Странно... Покажи цикл, там наверное косяк.
← →
VMcL © (2004-02-26 17:54) [2]>>Стандартным циклом оно не отправляется!
Что есть "Стандартный цикл"?
← →
Chapha (2004-02-26 17:58) [3]Может BrouteCast?
← →
Max003 (2004-02-26 18:03) [4]ПОКАЖИ ЦИКЛ, ПОКАЖИ!!!
← →
serg128 © (2004-02-26 18:06) [5]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 - текст сообщения
← →
Digitman © (2004-02-26 18:26) [6]оххх(( ...
← →
serg128 © (2004-02-26 18:28) [7]ну предложи что-то лучше, а не оххх((...
← →
Digitman © (2004-02-26 18:40) [8]
> serg128 © (26.02.04 18:28) [7]
предлагаю ... почитать этот форум "Сети" ... где коллеги уже языки до костей сточили, объясняя денно и нощно по нннадцать раз на дню, что гнездо в блокирующем режиме должно программироваться в прикладной задаче с обязательным осознанным ипользованием практически всех событий, которые предоставляет компонент TClientSocket !
ты задавался себе хоть раз вопросом, а нахрена столько событий у этого компонента, когда и при каких условиях и в какой последовательности они возбуждаются ?
← →
Digitman © (2004-02-26 18:42) [9]миль пардон, в неблокирующем ... он у тебя. очевидно. используется ... заморочился уже я(
← →
Digitman © (2004-02-26 18:44) [10]ClientSocket->Active = true; // ну, предположим ,активировал ты здесь коннект... точнее, стартовал механизм коннекта ...
ClientSocket->Open(); // а это зачем ??!
← →
Digitman © (2004-02-26 18:45) [11]
> Application->ProcessMessages();
это почему не в цикле ? ты вообще зачем эоту строчку поставил ? если осознанно, то в состоянии ли прокомментировать, что ты ожидаешь в рез-те ее исполнения ?
← →
Digitman © (2004-02-26 18:47) [12]
> ClientSocket->Socket->SendText(ods->FieldByName("TEX")->AsString);
где анализ рез-та вызова функции ?
> ClientSocket->Active = false;
почему, не проанализировав результат передачи как вызова метода SendText, тут же закрываешь гнездо ?
> ClientSocket->Close();
это зачем ?
← →
Verg © (2004-02-26 19:19) [13]Ух ты! Ну и дела...
Давай-ка экспромтом попробуем.
Пиво - "ПИТ", сокет - неблокирующий, язык - Делфи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.
Ну что, "чего не хватает в этом супе"? :)
← →
serg128 © (2004-02-26 19:32) [14]Была и такая идея, но таймер не катит, раз в 10 секунд - геморой. Но всё равно спасибо.
← →
Verg © (2004-02-26 19:39) [15]
> [14] serg128 © (26.02.04 19:32)
> Была и такая идея, но таймер не катит, раз в 10 секунд -
> геморой. Но всё равно спасибо.
В 10 секунд :)))
А не миллисекунд ли, а ?
Ну ты даешь, программер...
← →
serg128 © (2004-02-26 19:55) [16]тфу, гоню, согласен :))) так а мой пример разве плох? (Он кстати работает)
← →
Verg © (2004-02-26 20:28) [17]Так таймер там вообще PostMessage-заменитель. Раз уж схватился за TDataModule, то...
> так а мой пример разве плох? (Он кстати работает)
.......... Ну а что,
> Digitman ©
...тебе еще не объяснил чем плох?
Еше раз "языки стесывать"?
Ну работает - и ладно, Бог с тобой.
Когда перестанет работать, может и вспомнишь то, что тебе говорили...
> serg128 © (26.02.04 17:43)
> Как отправить одно сообщение на несколько машин с одной,
> используя сокеты.
> Стандартным циклом оно не отправляется! Помогите плиз! Спасибо!
Типа показалось? :))
Да и не для тебя я это писал...., просто это уже оскомину набило - объяснять как работают с сокетом в неблокирующем, а особенно в асинхронном режиме.
← →
Digitman © (2004-02-27 08:31) [18]
> Verg © (26.02.04 20:28) [17]
>[17] ????
не понял ?)
← →
Verg © (2004-02-27 08:36) [19]
> [18] Digitman © (27.02.04 08:31)
>
> > Verg © (26.02.04 20:28) [17]
>
>
> >[17] ????
>
> не понял ?)
Чего именно?
← →
Digitman © (2004-02-27 09:08) [20]
> Verg © (27.02.04 08:36) [19]
все, я въехал)
недоразумение просто приключилось)
← →
Rouse_ © (2004-02-27 09:29) [21]Короче вот тебе пример 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.
Желаю успехов
← →
Rouse_ © (2004-02-27 09:32) [22]Упс ссылки на FWUDPSocket убери - это лишнее...
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.038 c