IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Сокеты и консоль
сообщение
Сообщение #1


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Привет всем.

Животрепещущий вопрос: возможно ли в консоли присвоить событию сокета (OnRead, например) свою процедуру? Например, Client.onread:=myevent;. Описать её (myevent) получается, а вот присвоить правильно - нет..


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Можно посмотреть, как именно ты ее описываешь, и как пытаешься присвоить? smile.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


program Project1;

{$APPTYPE CONSOLE}

uses
Windows,
SysUtils,
Classes,
ScktComp,
Graphics;

var server:TServersocket;

Procedure EVENT1(Sender: TObject; Socket: TCustomWinSocket);
begin
writeln(socket.receivetext);
end;

begin
server:=TServerSocket.create(nil);
server.port:=1001;
server.OnClientRead:=event1(); //<===здесь, во входных параметрах, определённо нужно что--то написать
Server.ServerType:=stNonBlocking;
server.Open;
while server.active do sleep(100);
end.


По идее, должно быть server.OnClientRead:=event1(sender,socket);, но ведь в консоли нет понятия Sender, да?smile.gif


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






По идее Event1 должен быть методом класса, поскольку в типе TSocketNotifyEvent есть указание:
type TSocketNotifyEvent = procedure (Sender: TObject; Socket: TCustomWinSocket) of object;

(2 слова в конце видишь? smile.gif )

Итого, решение тривиальное - обернуть всю работу с сокетом своим классом:
type
TFooClass = class(TObject)
server:TServersocket;
procedure Event1(Sender: TObject; Socket: TCustomWinSocket);
end;



Procedure TFooClass.Event1(Sender: TObject; Socket: TCustomWinSocket);
begin
writeln(socket.receivetext);
end;

var
obj: TFooClass;
begin
obj := TFooClass.Create;
with obj do begin
server:=TServerSocket.create(nil);
server.port:=1001;
server.OnClientRead:=event1;
server.ServerType := stNonBlocking;
server.Open;
while server.active do sleep(100);
end;
obj.Free;
end.
Можешь еще добавить try/finally, как положено, и создавать сокет в конструкторе класса TFooClass...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Спасибо, вот так компилируется, ООП сила:)
Только вот будут ли обрабатываться события при таком описании? Я вот ради интереса попробовал в консоли сделать клиентскую и серверную части, просто чтобы можно было передать строку текста с клиента на сервер, вот что получилось.

Сервер:

program Project1;

{$APPTYPE CONSOLE}

uses
Windows,
SysUtils,
Classes,
ScktComp,
Graphics;

type
TFooClass = class(TObject)
server:TServersocket;
procedure Event1(Sender: TObject; Socket: TCustomWinSocket);
end;

Procedure TFooClass.Event1(Sender: TObject; Socket: TCustomWinSocket);
begin
writeln(socket.receivetext);
end;

var
obj:TFooClass;
begin
obj:=TFooClass.Create;
with obj do begin
server:=TServerSocket.create(nil);
server.port:=1001;
server.OnClientRead:=event1;
server.ServerType:=stNonBlocking;
server.Open;
while server.active do sleep(100);
end;
obj.Free;
end.



Клиент:

program Project1;

{$APPTYPE CONSOLE}

uses
Windows,
SysUtils,
Classes,
ScktComp,
Graphics;

type
TFooClass = class(TObject)
client:Tclientsocket;
procedure Event2(Sender: TObject; Socket: TCustomWinSocket);
end;

var host:string;
key:string;
Procedure TFooClass.Event2(Sender: TObject; Socket: TCustomWinSocket);
begin
writeln('СОЕДИНЕНО!!!');
end;

var
obj:TFooClass;
begin
writeln('Введите IP-адрес сервера');
readln(host);
obj:=TFooClass.Create;
with obj do begin
client:=TClientSocket.create(nil);
client.port:=1001;
client.Onconnect:=event2;
client.clientType:=CtNonBlocking;
client.Address:=host;
client.Open;
repeat
key:='';
readln(key);
client.Socket.SendText(key);
until key='EXIT';
end;
obj.Free;
end.



Вот на событие OnConnecting обработчик срабатывает, а на OnConnect никак, строка тоже не передаётся, хотя пробовал своим проектом на VCL подсоединиться к консольному серверу - получилось.


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Здесь помочь ничем не могу, это надо проверять, а проверять негде: я из-под Debian-а... Как попаду в WinXP - проверю...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Гость






Кстати... Вот сюда зайди: http://www.s2.org/flop.html , и посмотри исходники flop2 (предупреждаю сразу, написано на С, но вызовы API-функций они и в Африке вызовы), разбей их на клиент/сервер и пользуйся...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Цитата
Кстати... Вот сюда зайди: http://www.s2.org/flop.html , и посмотри исходники flop2 (предупреждаю сразу, написано на С, но вызовы API-функций они и в Африке вызовы), разбей их на клиент/сервер и пользуйся...


Ну, мне надо чтобы именно через Event'ы обрабатывались все события. Просто с одним человеком поспорил, он утверждал, что это невозможно - сделать запись в консоли client.Onconnect:=event2; и чтобы это вдобавок ко всему работало.. От программы достаточно, чтобы она хотя бы строку пересылала:)



--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гость






Звони своему "одному человеку", и требуй с него ящик пива smile.gif

1) клиент:
// Client
program Project1;
{$APPTYPE CONSOLE}

uses
ScktComp, windows;

type
TCustomWinSocketA = class helper for TCustomWinSocket
function ReceiveTextAnsi: AnsiString;
end;
function TCustomWinSocketA.ReceiveTextAnsi: AnsiString;
begin
SetLength(Result, ReceiveBuf(Pointer(nil)^, -1));
SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
end;


var
ClientMy:TClientSocket;
Msg:TMsg;

begin
ClientMy:=TClientSocket.Create(nil);
ClientMy.ClientType:=ctBlocking;
ClientMy.Address:='127.0.0.1';
ClientMy.Port:=8080;
ClientMy.Active:=true;
ClientMy.Socket.SendText('hello');
Sleep(5);
writeln(ClientMy.Socket.ReceiveTextAnsi);
while GetMessage(Msg,0,0,0) do DispatchMessage(Msg);
readln;
ClientMy.Free;
end.


2) сервер:
program Project1;
{$APPTYPE CONSOLE}

uses
ScktComp,SysUtils,windows;

type
TCustomWinSocketA = class helper for TCustomWinSocket
function ReceiveTextAnsi: AnsiString;
end;
function TCustomWinSocketA.ReceiveTextAnsi: AnsiString;
begin
SetLength(Result, ReceiveBuf(Pointer(nil)^, -1));
SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
end;

type
ServSock=class
serv:TServerSocket;
procedure ClientRead(Sender:TObject; Socket:TCustomWinSocket);
procedure ClientConnect(Sender:TObject; Socket:TCustomWinSocket);

public
constructor Create;
destructor Destroy; override;
end;

{ServSock}

constructor ServSock.Create;
Begin
inherited Create;
Serv:=TServerSocket.Create(nil);
Serv.ServerType:=stNonBlocking;
Serv.OnClientConnect:=ClientConnect;
Serv.OnClientRead:=ClientRead;
Serv.Port:=8080;
Serv.Active:=true;
End;

procedure ServSock.ClientRead(Sender:TObject; Socket:TCustomWinSocket);
var
a:ansistring;
Begin
a:=Socket.ReceiveTextAnsi;
Writeln(a);
if a='hello' then Socket.SendText('Hello goes back...');
End;

procedure ServSock.ClientConnect(Sender:TObject; Socket:TCustomWinSocket);
Begin
Socket.SendText('To Client: You are connected...');
End;

destructor ServSock.Destroy;
Begin
Serv.Free;
inherited Destroy;
End;

var
Server1:ServSock;
MSG: TMSG;

begin
Server1 := ServSock.Create;
try
while GetMessage(MSG, 0, 0, 0) do
begin
TranslateMessage(msg);
DispatchMessage(msg);
end;
finally
readln;
Server1.Free;
end;
readln;
end.
Все условия выполняются: все на Эвентах + окно консольное... Класс-Хелперы понадобились для того, чтоб программа была работоспособна на D2009 (без них в Юникодной версии Дельфи принимается совсем не то, что отсылается - баг в исходниках), если у тебя версия ниже 2009, то можешь Class Helper-ы смело убирать, а вместо ReceiveTextAnsi использовать обычный ReceiveText.

Проверялось на D2009 + WinXP SP3, работает... Запускается сначала сервер (как всегда), потом - клиент...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Volvo, спасибо, здорово, это его окончательно добило lol.gif good.gif Правда, за свой код выдавать не стал, ну для спора это значения не имеет) Вчера он говорил, что если это возможно, то он повесится) А про пиво не получится sad.gif , чел аж с Новгорода...(иначе сейчас бы меня на форуме не было))) .
Цитата

Все условия выполняются: все на Эвентах + окно консольное...


В выделенной части фразы подвох?smile.gif Теперь он прицепился к тому, что TranslateMessage(msg) и DispatchMessage(msg); - это Win32-функции, поэтому приложение не подходит под разряд консольного..

А ещё - мне становится страшно общаться со сверстником, который 14 лет из 16 программирует...


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






Ну, и что теперь, все, что подключает Windows.pas - будет считаться оконным? Тогда Сокеты вообще нельзя использовать, ибо они тоже там описаны. А консольное - потому, что GetStdHandle(STD_OUTPUT_HANDLE) вернет именно его хендл, а STD_OUTPUT_HANDLE это
Цитата(MSDN)
STD_OUTPUT_HANDLE (DWORD)-11 The standard output device. Initially, this is the active console screen buffer, CONOUT$.
( Цитата отсюда: http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx ) Претензии есть к MSDN/Microsoft за то, что консольное приложение тоже может обрабатывать очередь сообщений? smile.gif Ну, извините, про ее (очередь) отсутствие ничего не было сказано...

Добавлено через 1 мин.
Цитата
мне становится страшно общаться со сверстником, который 14 лет из 16 программирует...
Что же он программировал в 3 года, интересно? Погремушку свою, или соску? Тогда я программирую вообще страшно представить, сколько лет smile.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Цитата, ICQ:

Цитата
>10 лет паскаля 12 бейсика 5 лет си++ и 2 года ассемблера риальне сделали свое=)
>>я за компом с 2-3 непомню когда батя посадил он тоже прогер
(он имел в виду параллельно изучать)

Причём через некоторое время я понял, что это как минимум наполовину не пустые слова...
Бедный парень, света белого не видит.. wacko.gif

Извиняюсь за оффтоп:)


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 27.04.2024 12:41
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name