Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];

Вниз

КАК принять данные из DLL ?   Найти похожие ветки 

 
SerGH ©   (2006-05-06 13:00) [0]

Здравствуйте,уважаемые Мастера,здравствуйте,уважаемый Сергей М.Не могли бы Вы помочь.Есть две программки,назначение одной-отправка данных,назначение второй -прием данных.Связь м/у ними осуществляет DLL,состоящая из клиетской и серверной частей.Как передать данные из DLL в программу-приемник?


 
SerGH ©   (2006-05-06 13:03) [1]

Клиент:
unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Button3: TButton;
   CheckBox1: TCheckBox;
   Edit1: TEdit;
   Label1: TLabel;
   Memo1: TMemo;
   ListBox1: TListBox;
   ClientSocket1: TClientSocket;
   Panel1: TPanel;
   procedure Button2Click(Sender: TObject);
   procedure Button3Click(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure ClientSocket1Connect(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocket1Connecting(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocket1Disconnect(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
     ErrorEvent: TErrorEvent; var ErrorCode: Integer);
   procedure ClientSocket1Lookup(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
   procedure Edit1KeyDown(Sender: TObject; var Key: Word;
     Shift: TShiftState);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 nickname: string;

implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);
var do_connect: Boolean;
    host,port: string;
begin
{Показываем окно установки соединения с сервером}
 Form2 := TForm2.Create(Application);
 {do_connect = True, если была нажата кнопка Connect}
 do_connect := (Form2.ShowModal = mrOk);
 {заполнение переменных до того, как мы уничтожим форму}
 host := Form2.Edit1.Text;
 port := Form2.Edit2.Text;
 nickname := Form2.Edit3.Text;
 {Уничтожаем форму}
 Form2.Free;
 {Если была нажата кнопка Cancel, то уходим отсюда}
 if not do_connect then
  Exit;
 {Если соединение уже установлено, то обрываем его}
 if ClientSocket1.Active then
  ClientSocket1.Close;
 {Устанавливаем свойства Host и Port}
 ClientSocket1.Host := host;
 ClientSocket1.Port := StrToInt(port);
 {Пытаемся соединиться}
 ClientSocket1.Open;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
{Закрываем соединение (если оно установлено)}
 if ClientSocket1.Active then
  ClientSocket1.Close;
end;

procedure TForm1.Button1Click(Sender: TObject);
var s: string;
begin
{Если хотим послать приватное сообщение, но не выбрали адресата -
  выводится замечание,затем следует выход из обработчика}
 if (CheckBox1.Checked)and(ListBox1.ItemIndex < 0) then begin
  ShowMessage("At first you should select the user in the User List!");
  Exit;
end;
{Если это приватное сообщение}
 if CheckBox1.Checked then
  s := "#P"+ListBox1.Items[ListBox1.ItemIndex]+";" {добавляем спец.команду и адресат}
 else { Если не приватное}
  s := "#M"; {Просто спец.команду}
 {Добавляем наше имя (от кого) и само сообщение}
 s := s+nickname+";"+Edit1.Text;
 {Посылаем все это по сокету}
 ClientSocket1.Socket.SendText(s);
 {И снова ждем ввода в уже чистом TEdit-е}
 Edit1.Text := "";
 ActiveControl := Edit1;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
{соединились!}
 Memo1.Lines.Insert(0,"connected!");
end;

procedure TForm1.ClientSocket1Connecting(Sender: TObject;
 Socket: TCustomWinSocket);
begin
 {соединяемся...}
 Memo1.Lines.Insert(0,"connecting...");
end;

procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
{отсоединились }
 Memo1.Lines.Insert(0,"disconnected");
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
 Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
 var ErrorCode: Integer);
begin
{Если произошла ошибка, выводим ее код в Memo1}
 {Insert вставляет строку в указанную позицию (в данном случае - 0 - в начало)}
 Memo1.Lines.Insert(0,"Socket error ("+IntToStr(ErrorCode)+")");
end;

procedure TForm1.ClientSocket1Lookup(Sender: TObject;
 Socket: TCustomWinSocket);
begin
{Сообщаем о том, что идет поиск хоста}
 Memo1.Lines.Insert(0,"Looking up for server...");
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
 Socket: TCustomWinSocket);
 var s,from_,to_: string;
begin
{присваиваем s полученную от сервера строку}
 s := Socket.ReceiveText;
 {Если сервер посылает нам User List}
 if Copy(s,1,2) = "#U" then begin
  Delete(s,1,2);
  {Чистим ListBox1}
  ListBox1.Items.Clear;
  {Добавляем по одному пользователю в список.
  Имена пользователей разделяем знаком ";"}
  while Pos(";",s) > 0 do begin
   ListBox1.Items.Add(Copy(s,1,Pos(";",s)-1));
   Delete(s,1,Pos(";",s));
end;
 Exit;
 end;
 {Если нам прислали общее сообщение (видимое для всех)}
 if Copy(s,1,2) = "#M" then begin
  Delete(s,1,2);
  {Добавляем его в Memo1}
  Memo1.Lines.Insert(0,Copy(s,1,Pos(";",s)-1)+"> "+
                       Copy(s,Pos(";",s)+1,Length(s)-Pos(";",s)));
  Exit;
 end;
 {Если нам прислали запрос на наше имя }
 if Copy(s,1,2) = "#N" then begin
  {Посылаем ответ}
  Socket.SendText("#N"+nickname);
  Exit;
 end;
 {Если прислали приватное сообщение }
 if Copy(s,1,2) = "#P" then begin
  Delete(s,1,2);
  {Выделяем в to_ - кому оно предназначено}
  to_ := Copy(s,1,Pos(";",s)-1);
  Delete(s,1,Pos(";",s));
  {Выделяем в from_ - кем отправлено}
  from_ := Copy(s,1,Pos(";",s)-1);
  Delete(s,1,Pos(";",s));
  {Если оно для нас, или написано нами - добавляем в Memo1}
  if (to_ = nickname)or(from_ = nickname) then
   Memo1.Lines.Insert(0,from_+" (private) > "+s);
  Exit;
 end;
end;
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
begin
 {Если была нажата Enter - тоже не
  отказываемся послать сообщение}
 if Key = VK_RETURN then
  Button1.Click;
end;

end.

unit Unit2;

interface

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

type
 TForm2 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Host: TLabel;
   Port: TLabel;
   nickname: TLabel;
   Edit1: TEdit;
   Edit2: TEdit;
   Edit3: TEdit;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

{$R *.dfm}

end.


 
SerGH ©   (2006-05-06 13:04) [2]

Сервер:
unit Server_main;

interface

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

type
 TForm1 = class(TForm)
   Panel1: TPanel;
   Button1: TButton;
   Button2: TButton;
   ListBox1: TListBox;
   Panel2: TPanel;
   ServerSocket1: TServerSocket;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure ServerSocket1ClientRead(Sender: TObject;
   Socket: TCustomWinSocket);
   procedure ServerSocket1ClientDisconnect(Sender: TObject;
   Socket: TCustomWinSocket);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var s: string;
begin
{Запрашиваем порт}
s := InputBox(" START Server","Enter port:","5577");
if s ="" then
Exit;
{Очистка пользовательского листа}
ListBox1.Items.Clear;
{Устанавливаем порт}
ServerSocket1.Port := StrToInt(s);
{Запускаем сервер}
ServerSocket1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
{Очистка пользовательского листа и остановка сервера}
ListBox1.Items.Clear;
if ServerSocket1.Active then
ServerSocket1.Close;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var s: string;
   i: Integer;
begin
{Сохраняем в s присланную нам строку}
s:= Socket.ReceiveText;
{Если кто-то прислал нам своё имя}
if Copy(s,1,2) = "#N" then begin
Delete(s,1,2);
{Добавляем его в полsьзовательский лист}
ListBox1.Items.Add(s);
{Записываем в s команду для посылки нового списка пользователей}
s:= "#U";
for i :=0 to ListBox1.Items.Count-1 do
s:= s+ListBox1.Items[i]+";";
{...и рассылаем этот список всем клиентам}
for i:=0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText(s);
Exit;
end;
{Если кто-то отправил сообщение - рассылаем его всем клиентам}
if (Copy(s,1,2) = "#M")or(Copy(s,1,2) = "#P") then begin
for i :=0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText(s);
Exit;
end;
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
 Socket: TCustomWinSocket);
var i: Integer;
begin
 {Кто-то присоединился или отсоединился?  Запрашиваем у всех
  пользователей их имена}
 ListBox1.Items.Clear;
 for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
  ServerSocket1.Socket.Connections[i].SendText("#N");
end;


 
SerGH ©   (2006-05-06 13:05) [3]

Как из этих программ сделать DLL? Заранее благодарен Вам.


 
Сергей М. ©   (2006-05-06 13:12) [4]

"В лоб" - никак.
Придется практически все "перелопаптить".

Но перед этим следует разработать протокол инф.взаимодействия между хост-приложениями и будущей DLL, которую они будут использовать.
С этого и начни.
Только после этого можно говорить о "переделке".


 
Сергей М. ©   (2006-05-06 13:20) [5]

А каков вообще смысл такой "переделки" ?


 
SerGH ©   (2006-05-06 13:41) [6]

У меня задание: создание универсальной библиотеки для передачи данных по сетям TCP/IP.


 
Сергей М. ©   (2006-05-06 13:46) [7]

Странное задание.
"Универсальность" - понятие растяжимое...


 
konischev ©   (2006-05-06 14:29) [8]

Здравствуйте, Сергей М. Мы с SerGH"ем одногруппники. Ситуация такая. Мы написали две проги которые позволяют обмениваться данными разных типов используя record. Одна прога - сервер, другая - клиент. Преподаватель поставил задачу сделать DLL которая будет передавать данные любого типа используя TCP/IP протокол. Как написать DLL мы примерно знаем, пробовали уже, но возникла проблема ->  когда DLL примет данные нужно вывести их в основное окно программы, как это сделать?


 
SerGH ©   (2006-05-06 15:07) [9]

универсальные данные-данные любого типа:integer,string и т.п.


 
Сергей М. ©   (2006-05-06 15:24) [10]


> когда DLL примет данные нужно вывести их в основное окно
> программы, как это сделать?


"Основная" программа - это Делфи-приложение ? Или написанное на любом (заранее неизвестном) языке программирования ? Это очень важно ..


> универсальные данные-данные любого типа:integer,string и
> т.п.


В этом плане об "универсальности" не может быть и речи.
Все зависит от конкретного типа данных.


 
Konischev ©   (2006-05-06 15:48) [11]

Да, естественно основная программа на Делфи.
Типы: integer, real, string, boolean. С типами мы сами, я думаю, разберемся.
А как выкидывать данные из DLL в прогу? Вот самый главный вопрос...


 
SerGH ©   (2006-05-06 15:55) [12]

Любые данные


 
Сергей М. ©   (2006-05-06 16:03) [13]

Один говорит "любые", другой - только "integer, real, string, boolean") ..

Вы уж как-нибудь определитесь с конечным перечнем типов !


> как выкидывать данные из DLL в прогу?


Не надо их "выкидывать".
Следует, вероятно, реализовать и экспортировать ф-ции вида

function GetReceivedDataOfSomeType(Timeout: Integer; var Data: SomeType): Boolean;


 
konischev ©   (2006-05-06 17:47) [14]

Ладно будем пробовать. Т.е. как я понял программа будет через определенные промежутки времени(Timeout) импортировать данные из DLL?
А насчет типов я думаю этих хватит, для описания любых данных будь то температура, давление, скорость и т.д. и т.п.


 
SerGH ©   (2006-05-06 19:51) [15]

Спасибо


 
Сергей М. ©   (2006-05-09 19:16) [16]


> программа будет через определенные промежутки времени(Timeout)
> импортировать данные из DLL?


Это зависит от конкретной реализации.
Можно "через определенные промежутки времени", можно с использованием того или иного механизма нотификаций ... на то и "универсальность" ..


 
Slym ©   (2006-05-10 05:49) [17]

SerGH ©   (06.05.06 15:07) [9]
универсальные данные-данные любого типа:integer,string и т.п.

WinSock это умеет :)

Ряд неясеностей:
1. Будут это простые типы данных или сложные (record, array)?
2. Принимающая сторона знает что принимает или заранее ей не известен тип/размер принимаемых данных. (принял 4 байта стринга, а на самом деле это интегер :(

Оба упираются в отсутствие "протокола" обмена
Если типы данных сложные бери за основу XML, там и имя переменной и тип и прочие атрибуты.
если простой тип данных то протокол можно упростить.



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.011 c
2-1157830754
Димон
2006-09-09 23:39
2006.10.01
Объявление типов


4-1148668623
PRT
2006-05-26 22:37
2006.10.01
как поменять свойство ReadOnly контрола в чужом приложении ??


15-1157977985
Tab
2006-09-11 16:33
2006.10.01
Кто как делает Разграничение доступа в программе?


15-1157989615
Cyrax
2006-09-11 19:46
2006.10.01
Тонкости языка C++


2-1157715613
Alral
2006-09-08 15:40
2006.10.01
Poisk v TKomboBox





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский