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

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

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.05.2012, 10:26   #1
raketa161
 
Аватар для raketa161
 
Регистрация: 14.03.2012
Сообщений: 8
По умолчанию передать массив через Socket.SendBuf();

Добрый день.
найдите минутку, помочь мне.

Необходимо написать две программы

1 программа - Client;
передавать по протоколу
1 байт - 39; //постоянное
2 байт - число (счетчик);
3 байт - число;
4 байт - число;
5 байт - число;

2 программа - Server; - приём этого "протокола"


помогите разобраться как правильно осуществить передачу и приём, я так понял Socket.SendBuf();

//программа Client; - передача
Код:
unit Client;
......
var
  Form2          : TForm2;
  Server         : string;
  i                 : integer;
  ByteW         : array[0..5]  of Byte;
 
implementation
{$R *.DFM}
procedure TForm2.Button1Click(Sender: TObject);
var Server:String;
begin
if ClientSocket1.Active then ClientSocket1.Active:=False;
if InputQuery('Установить связь с ','IP-адрес:',Server) then
if Length(Server)>0 then
with ClientSocket1 do
begin
host:=Server;
Active:=True;
end;
end;
 
 
procedure TForm2.Button2Click(Sender: TObject);
begin
 ClientSocket1.Active:=False;
end;
 
procedure TForm2.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  StatusBar1.Panels[0].Text:='Соединено с адресом:'+Socket.LocalHost;
end;
 
procedure TForm2.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
StatusBar1.Panels[0].Text:='Соединение закрыто';
end;
 
procedure TForm2.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
 Memo2.Lines.Add('ошибка соединения с сервером:'+ Server);
 ErrorCode:=0;
end;
 
 
procedure TForm2.FormCreate(Sender: TObject);
begin
 Memo2.Clear;
end;
 
 
procedure TForm2.Button3Click(Sender: TObject);
begin
ByteW[0]:=39; //постоянное
ByteW[1]:=136;
ByteW[2]:=136;
ByteW[3]:=136;
ByteW[4]:=136;
ByteW[5]:=136;
ClientSocket1.Socket.SendBuf(ByteW,6);
end;
end.


//программа Server; - приём
Код:
unit Server;
var
  Form1    : TForm1;
  ByteR    :array[0..5] of byte;
  len        :byte;
implementation
{$R *.DFM}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
ServerSocket1.Active:=True;
StatusBar1.Panels[0].Text:='Прослушивание';
end;
 
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Memo2.Lines.Add('ServerSoket1ClientConnect');
end;
 
procedure TForm1.ServerSocket1Accept(Sender: TObject;
  Socket: TCustomWinSocket);
begin
 Memo2.Lines.Add('ServerSocket1Accept');
 StatusBar1.Panels[0].Text:='Соединено с:'+Socket.LocalAddress;
end;
 
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
 StatusBar1.Panels[0].Text:='Клиент отсоединился. Прослушивание соединения...';
end;
 
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
 ServerSocket1.Socket.ReceiveBuf(ByteR,6);
 Memo2.Lines.Add(inttostr(ByteR[0]));
 Memo2.Lines.Add(inttostr(ByteR[1]));
 Memo2.Lines.Add(inttostr(ByteR[2]));
 Memo2.Lines.Add(inttostr(ByteR[3]));
 Memo2.Lines.Add(inttostr(ByteR[4]));
 Memo2.Lines.Add(inttostr(ByteR[5]));
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo2.Clear;
end;
end.

ошибка возникает в программе Server; - при приёме
windows socket error: запрос на отправку или получение данных (when seding on a datagram socket using s sendto call) no adress was supplied (10057), on API 'recv'

Последний раз редактировалось raketa161; 11.05.2012 в 10:28.
raketa161 вне форума Ответить с цитированием
Старый 11.05.2012, 11:16   #2
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Попробуй сделать так
Код:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);

begin
 Socket.ReceiveBuf(Pointer(@ByteR)^, SizeOf(ByteR));
 Memo2.Lines.Add(inttostr(ByteR[0]));
 Memo2.Lines.Add(inttostr(ByteR[1]));
 Memo2.Lines.Add(inttostr(ByteR[2]));
 Memo2.Lines.Add(inttostr(ByteR[3]));
 Memo2.Lines.Add(inttostr(ByteR[4]));
 Memo2.Lines.Add(inttostr(ByteR[5]));
end;
Либо так
Код:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
Buf: pointer;
begin
GetMem(Buf, SizeOf(ByteR));
try
 Socket.ReceiveBuf(Buf^, SizeOf(ByteR));
 Move(Buf^, ByteR, SizeOf(ByteR));
 Memo2.Lines.Add(inttostr(ByteR[0]));
 Memo2.Lines.Add(inttostr(ByteR[1]));
 Memo2.Lines.Add(inttostr(ByteR[2]));
 Memo2.Lines.Add(inttostr(ByteR[3]));
 Memo2.Lines.Add(inttostr(ByteR[4]));
 Memo2.Lines.Add(inttostr(ByteR[5]));
finnaly
freeMem(Buf);
end;
end;
И вообще почему бы тебе не сделать массив типа record

Последний раз редактировалось Aliens_wolfs; 11.05.2012 в 11:35.
Aliens_wolfs вне форума Ответить с цитированием
Старый 11.05.2012, 11:42   #3
raketa161
 
Аватар для raketa161
 
Регистрация: 14.03.2012
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
Попробуй сделать так
Код:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);

begin
 Socket.ReceiveBuf(Pointer(@ByteR)^, SizeOf(ByteR));
 Memo2.Lines.Add(inttostr(ByteR[0]));
 Memo2.Lines.Add(inttostr(ByteR[1]));
 Memo2.Lines.Add(inttostr(ByteR[2]));
 Memo2.Lines.Add(inttostr(ByteR[3]));
 Memo2.Lines.Add(inttostr(ByteR[4]));
 Memo2.Lines.Add(inttostr(ByteR[5]));
end;


И вообще почему бы тебе не сделать массив типа record
ошибка таже((((
raketa161 вне форума Ответить с цитированием
Старый 11.05.2012, 12:02   #4
raketa161
 
Аватар для raketa161
 
Регистрация: 14.03.2012
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
Попробуй сделать так
Либо так
Код:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
Buf: pointer;
begin
GetMem(Buf, SizeOf(ByteR));
try
 Socket.ReceiveBuf(Buf^, SizeOf(ByteR));
 Move(Buf^, ByteR, SizeOf(ByteR));
 Memo2.Lines.Add(inttostr(ByteR[0]));
 Memo2.Lines.Add(inttostr(ByteR[1]));
 Memo2.Lines.Add(inttostr(ByteR[2]));
 Memo2.Lines.Add(inttostr(ByteR[3]));
 Memo2.Lines.Add(inttostr(ByteR[4]));
 Memo2.Lines.Add(inttostr(ByteR[5]));
finnaly
freeMem(Buf);
end;
end;
И вообще почему бы тебе не сделать массив типа record
вот так - работает.

Aliens_wolfs, большое спасибо, что нашел время и помог

Последний раз редактировалось raketa161; 11.05.2012 в 12:21.
raketa161 вне форума Ответить с цитированием
Старый 12.05.2012, 09:59   #5
raketa161
 
Аватар для raketa161
 
Регистрация: 14.03.2012
Сообщений: 8
По умолчанию

у меня ещё один вопрос...

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

создал поток TEnetWThread, и как мне в procedure TEnetWThread.Execute; передать данные

//ClientSocket1.Socket.SendBuf(ByteW, sizeof(ByteW));

Код:
unit Client;

interface

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

type  
  TEnetWThread = class(TThread)
   private
     procedure UpdateIndW;
   protected
     procedure Execute; override;
  end;

type
  TForm2 = class(TForm)
    Memo2: TMemo;
    ClientSocket1: TClientSocket;
    StatusBar1: TStatusBar;
    Button1: TButton;
    Button2: TButton;
    Label2: TLabel;
    Button3: TButton;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label16: TLabel;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure FormCreate(Sender: TObject);

    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2                 : TForm2;
  EthernetWThread       : TEnetWThread;
  Server                : string;
  i                     : integer;
  ByteW                 : array[0..5]  of Byte;
implementation

{$R *.DFM}


//отображение   данных
procedure TEnetWThread.UpdateIndW;
begin
 Form2.Label16.Caption:=inttostr(ByteW[0]);
 Form2.Label10.Caption:=inttostr(ByteW[1]);
 Form2.Label11.Caption:=inttostr(ByteW[2]);
 Form2.Label12.Caption:=inttostr(ByteW[3]);
 Form2.Label13.Caption:=inttostr(ByteW[4]);
 Form2.Label14.Caption:=inttostr(ByteW[5]);
end;


//ПРОЦЕДУРЫ ПОТОКА
//Передача
procedure TEnetWThread.Execute;
begin
 repeat
  Sleep(10);
  if i>255 then i:=0;
  ByteW[0]:=39; //постоянное
  ByteW[1]:=i;  //счетчик
  ByteW[2]:=136;
  ByteW[3]:=136;
  ByteW[4]:=136;
  ByteW[5]:=136;
  //отправить
  ClientSocket1.Socket.SendBuf(ByteW,sizeof(ByteW));
  Synchronize(UpdateIndW);
  inc(i);
 until Terminated;
end;


//соединиться
procedure TForm2.Button1Click(Sender: TObject);
begin
 ClientSocket1.Host:='192.168.1.1';
 ClientSocket1.Active:=True;
end;

//закрыть соединение
procedure TForm2.Button2Click(Sender: TObject);
begin
 ClientSocket1.Active:=False;
end;

procedure TForm2.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
 StatusBar1.Panels[0].Text:='Соединено с адресом:'+Socket.LocalHost;
end;

procedure TForm2.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
 StatusBar1.Panels[0].Text:='Соединение закрыто';
end;

procedure TForm2.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
 Memo2.Lines.Add('ошибка соединения с сервером:'+ Server);
 ErrorCode:=0;
end;


procedure TForm2.FormCreate(Sender: TObject);
begin
 Memo2.Clear;
end;

//кнопка передать
procedure TForm2.Button3Click(Sender: TObject);
begin
i:=0;
EthernetWThread:=TEnetWThread.Create(True);
EthernetWThread.Priority:=tpNormal;
EthernetWThread.Resume;
end;
  

//прекратить передачу
procedure TForm2.Button4Click(Sender: TObject);
begin
//Остановка потока передачи
 if EthernetWThread<>nil then
  begin
   EthernetWThread.Terminate; EthernetWThread.Free; EthernetWThread:=nil;
  end;
end;
end.
raketa161 вне форума Ответить с цитированием
Старый 12.05.2012, 13:01   #6
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Зачем поток делать для передачи небольшх данных, тем более что в работе с ним нужно учитывать многое.
Можно попробовать сделать проще
Код:
var
  Form1    : TForm1;
  ByteR    : array[0..5] of byte;
  Stoped   : boolean;

implementation
{$R *.DFM}

//кнопка передать
procedure TForm2.Button3Click(Sender: TObject);
var
i: integer;
begin
Stoped:=false;
 repeat
  application.ProcessMessages; //это нужно чтобы программа неподвисала работая с циклом
  WaitForSingleObject(Handle, 10); //пауза но можно и sleep(10)
  if i>255 then i:=0;
  ByteW[0]:=39; //постоянное
  ByteW[1]:=i;  //счетчик
  ByteW[2]:=136;
  ByteW[3]:=136;
  ByteW[4]:=136;
  ByteW[5]:=136;
  //отправить
  ClientSocket1.Socket.SendBuf(ByteW,sizeof(ByteW));
  inc(i);
 Until Stoped ;
end; 

//прекратить передачу
procedure TForm2.Button4Click(Sender: TObject);
begin
Stoped:=true;
end;
Если хочешь в потоке то лучше создать в нем TClientSocket и его события, похожие примеры для потока здесь есть, поисковиком воспользуйтесь.

Последний раз редактировалось Aliens_wolfs; 12.05.2012 в 13:22.
Aliens_wolfs вне форума Ответить с цитированием
Старый 12.05.2012, 16:16   #7
raketa161
 
Аватар для raketa161
 
Регистрация: 14.03.2012
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
Если хочешь в потоке то лучше создать в нем TClientSocket и его события, похожие примеры для потока здесь есть, поисковиком воспользуйтесь.
Aliens_wolfs, спасибо за помощь, но не могу найти или я туплю...
если не затруднит, ткните (ссылку)

искал так http://www.google.ru/search?q=TClientSocket+siterogram mersforum.ru&hl=ru
raketa161 вне форума Ответить с цитированием
Старый 12.05.2012, 16:41   #8
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Ищи примеры потоков для Indy там нетрудно переделать под TClientSocket
Aliens_wolfs вне форума Ответить с цитированием
Старый 12.05.2012, 17:51   #9
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,442
По умолчанию

Цитата:
1 байт - 39; //постоянное
2 байт - число (счетчик);
3 байт - число;
4 байт - число;
5 байт - число;
Превращаем в это:
Код:
Type 
  TPackedData=record
  Static:byte;
  Counter:Byte;
  bytes:array of byte; 
  end;

и дальше уже всяекими SendBuf швыряемся в клиента.
Человек_Борща вне форума Ответить с цитированием
Старый 12.05.2012, 17:51   #10
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Вот пример с потоком
Можно добавить туда записи record как предложил Человек_Борща так удобнее и правильнее
Вложения
Тип файла: rar SockThead.rar (182.9 Кб, 71 просмотров)

Последний раз редактировалось Aliens_wolfs; 12.05.2012 в 23:47.
Aliens_wolfs вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ip через socket xil C# (си шарп) 2 28.07.2011 19:14
Как передать структуру через socket moiav Общие вопросы C/C++ 6 18.05.2011 16:27
Передать двумерный массив через сокет (Debian) Phaeleh Qt и кроссплатформенное программирование С/С++ 1 29.11.2010 07:08
Как правильно передать через ссылку двумерный динамический массив? amerhant Общие вопросы C/C++ 2 21.04.2010 23:50
Socket.SendBuf\ResiveBuf SunKnight Работа с сетью в Delphi 7 13.06.2008 12:43