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

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

Как сделать пакет данных??? [D7, Win2k]


новичок111 ©   (2006-04-02 16:38:00) 

Здраствуйте, я только начал изучать Delphi, и никак не могу понять как сделать пакет данных которые потом нужно переслать другому компу по сети...
Например: заголовок-8 байт, данные 1000 байт, контрольная сумма - 4 байт.
Как это написать - реализовать, подскажите пожалуйста...


новичок111   (2006-04-05 21:55:00) [1]

ладно, но про сетевое программирование в делфи, я книг вообще не видел, к сожалению, все что смог найти это маленькие статьи и всё, но нигде про это не сказано ни слова... буду сам пробовать методом тыка, спасибо за помощь...


Джо   (2006-04-05 21:50:00) [2]

После ознакомления кода в [15] я решил не отвечать. Думаю, что в данном случае просто необходима книга по основам языка, а не какая-то смутная возня с "пакетами данных". Извини, но считаю это бесполезным.


новичок111   (2006-04-05 21:35:00) [3]


> С каких это пор "пинг" счетчик? ;)

я имел ввиду и как счетчик вписать, а не то что вы подумали...
Ping - имеет всегда одно и тоже значение.
Листинг, ничего  не работает где я это писать должен(пишет что типы необъявлены, хотя все объявлено, я хоть правильно вставил):
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ScktComp, StdCtrls, ExtCtrls;

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   Edit1: TEdit;
   Label1: TLabel;
   Button1: TButton;
   Button2: TButton;
   ClientSocket1: TClientSocket;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);

 private
   { Private declarations }
 public
   { Public declarations }
 end;
type
TMyPacket = packed record
  Ping: array [0..3] of Char;
 Info: Cardinal;

end;

var
 Form1: TForm1;
 packet: TMyPacket;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
Ping:='Ping';
Inc(Info);

.........................

end;
......................


Джо   (2006-04-05 21:13:00) [4]

Id: Cardinal;
...
Inc(Id);

Кстати, рекоммендую по-человечески назвать поля.
Id — это идентификатор. И операции +, Inc к нему мало подходят. Возможно, стоит назвать его Count (кол-во) или Counter (счетчик).

Ping — не назвать ли его Signature, если он всегда имеет одно значение?


Джо   (2006-04-05 21:10:00) [5]

> это слово пинг(счетчик)

С каких это пор "пинг" счетчик? ;)


Джо   (2006-04-05 21:10:00) [6]

Ping: array [0..3] of Char;
...
Ping := 'ping';


новичок111   (2006-04-05 20:54:00) [7]

Хорошо, а как примерно надо вписать туда это слово пинг(счетчик) и самое главное где это вписать??? я как не задаю, он мне пишет что неправильный тип...


Джо   (2006-04-05 20:41:00) [8]

Cardinal — это 4 байта.


новичок111   (2006-04-05 20:40:00) [9]

мне нужно чтобы пакет был 8 байт, поэтому я их так поделил...
вы не напишите примерный листинг как это будет выглядеть...


Джо   (2006-04-05 20:24:00) [10]

> [7] новичок111   (05.04.06 20:22)

Ну, а помему бы сразу тогда и не объявить
ID: Cardinal
и т.д.


новичок111   (2006-04-05 20:22:00) [11]

послать получилось, но вот возник вопрос, весь день себе голову ломал...
пакет данных как объявлять я понял:
type
TMyPacket = packed record
ID: array [0..3] of Byte;
Info: array [0..3] of Byte;
end;

но вот в этом пакете мне нужно чтобы Info имело значение строку ping, т.е.
ping=4 байта и в нем содержится только надпись ping...
А в ID мне нужно сделать счетчик и он тоже должен быть равен 4 байтам, т.е. ID:=schet; schet:=schet+1;
неподскажете где это писать и как???


Сергей М.   (2006-04-05 09:03:00) [12]


> что я не так делаю


Начнем с клиента.

Поскольку ClientSocket у тебя по всей вероятности работает в режиме ctNonBlocking, многие его св-ва/методы работают асинхронно.

procedure TForm1.Button1Click(Sender: TObject);
var
 BytesQueued: Integer;
begin
...
ClientSocket1.Active:=True; //это еще не факт полной и успешной активации клиента, тем самым всего лишь запущена операция установления коннекта с сервером, которая завершится либо событием OnConnect (успешно) либо событием OnError (не успешно)

//лучше и правильней всего будет выполнить SendBuf() в обработчике события OnWrite (факт готовности гнезда к передаче данных, еще точнее - факт освобождения внутреннего буфера передачи гнезда), следующем сразу за событием OnConnect

//но можно, в принципе, сделать и так:
while not ClientSocket1.Active do //!!!
 Application.Processmessages;

//и уже только по факту обнаружения истинности условия ClientSocket1.Active = True выполнять прием/передачу данных

BytesQueued :=ClientSocket1.Socket.SendBuf(packet,8); //обязательно проверять результат вызова send-метода ! Он покажет, сколько байт действительно было записано в очередь передачи

//Если при этом окажется, что BytesQueued = -1, следует повторить вызов send-метода позже, но не ранеечем возникнет ближайшее по времени событие OnWrite

end;


новичок111   (2006-04-04 21:29:00) [13]

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

сервер
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ScktComp;

type
 TForm1 = class(TForm)
   ServerSocket1: TServerSocket;
   Edit1: TEdit;
   procedure FormCreate(Sender: TObject);
   procedure ServerSocket1ClientRead(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
ServerSocket1.Active:=True;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
pak: Integer;
begin
pak:=Socket.ReceiveLength;
Edit1.Text:='пакет получен';
if pak=8 then
 begin
  ServerSocket1.Socket.SendText('принял');
  Edit1.Text:='пакет получен';
 end
else
 begin
  ServerSocket1.Socket.SendText('ошибка');
  Edit1.Text:='пакет не получен';
 end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
ServerSocket1.Active:=False;
end;

end.


клиент
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ScktComp, StdCtrls;

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   Edit1: TEdit;
   Label1: TLabel;
   Button1: TButton;
   Button2: TButton;
   ClientSocket1: TClientSocket;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
type
TMyPacket = packed record
 ID: array [0..3] of Byte;
 Info: array [0..3] of Byte;
end;

var
 Form1: TForm1;
 packet: TMyPacket;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Host:=Edit1.Text;
ClientSocket1.Active:=True;
ClientSocket1.Socket.SendBuf(packet,8);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ClientSocket1.Active:=False;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
 Socket: TCustomWinSocket);
var
pak: String;
begin
pak:=Socket.ReceiveText;
if pak='принял' then ClientSocket1.Socket.SendBuf(packet,8);
end;

end.


Delphi_is_cool   (2006-04-02 22:59:00) [14]


> спасибо, но что лучше использовать компоненты Indy или эти
> которые ты привел?

Это зависет от того что тебе нужно, если просто установить соединение послать пакет(т.е если будешь работать как бы по своему протоколу) то я считаю что лучше те, которые я привёл(не то что лучше, скорей проще, - на мой взгяд).


VirEx   (2006-04-02 21:37:00) [15]

CREATE TABLE 'packed' (
 Header int(7),
 Buffer int(999),
 ChkSum int,
);
INSERT INTO 'packed' VALUES (256,999,1);

^)


новичок111   (2006-04-02 21:30:00) [16]

спасибо, но что лучше использовать компоненты Indy или эти которые ты привел?


Delphi_is_cool   (2006-04-02 20:26:00) [17]


 TMyPacket = packed record
   Header: array [0..7] of Byte; // заголовок-8 байт
   Buffer: array [0..999] of Byte; // данные 1000 байт
   ChkSum: DWORD; // контрольная сумма - 4 байт.
 end;


Для работы с сетью, можешь использовать компоненты TServerSocket и TClientSocket, а учиться работать с ними, боюсь тебе придётся самому ...


Наверх

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