Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.11.13;
Скачать: CL | DM;

Вниз

Надёжный способ приёма   Найти похожие ветки 

 
delpher_gray ©   (2003-09-17 11:16) [0]

Вот заготовка программы:
program PServer;

uses
SysUtils, ScktComp, Windows;

type
TServer = class
private
procedure ClientConnectEvent(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientReadEvent(Sender: TObject; Socket: TCustomWinSocket);
end;

var
hMutex: THandle;
ServerClass: TServer;
ServerSocket1: TServerSocket;
Msg: TMSG;
Cancel: boolean;

procedure TServer.ClientConnectEvent(Sender: TObject; Socket: TCustomWinSocket);
begin
// CODE
end;

procedure TServer.ClientReadEvent(Sender: TObject; Socket: TCustomWinSocket);
begin
// CODE
end;

begin
hMutex := CreateMutex(nil, false, "Server");
if WaitForSingleObject(hMutex, 0) <> wait_TimeOut then
begin
ServerSocket1 := TServerSocket.Create(nil);
ServerSocket1.ServerType := stNonBlocking;
ServerSocket1.Port := 1379;

try
ServerSocket1.Open;
except
Cancel := true;
end;

while not Cancel do
begin
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
Sleep(5);
end;

ServerSocket1.Close;
ServerSocket1.Free;
end;
end.


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


 
Digitman ©   (2003-09-17 11:22) [1]

а какие вообще сомнения в надежности ?
в связи с чем такой вопрос возник ?


 
Verg ©   (2003-09-17 15:03) [2]


> TServer.


К чему описание этого класса?
Каким боком TServer участвует в программе?


 
zippo   (2003-09-17 19:13) [3]

&&&&


 
Slym ©   (2003-09-18 05:10) [4]

Все упирается в протокол обмена сообщениями!
Сделай типа разделы команд:
FILE
SHELL
CMD
и пр.
а далее подразделы типа:
FILE LOAD
FILE UPLOAD
FILE LIST
FILE DIR
для файл можно использовать например команды ftp протокола...
SHELL EXECUTE

А после команды параметры например с "комма делиметром":
FILE UPLOAD file="c:\autoexec.bat";size=1024
Команду завершай например #13#10 (перевод строки) или #0 (как в пичар)
А далее (для команды FILE UPLOAD file...) сам файл все 1024 байта
FILE LIST directory="c:\";mask="*.*";atrib="FDARSH";style="NSAD"
atrib:File,Dir,Archive,Readonly,Sys,Hiddden
style:Name,Size,Attrib,Date
Отват на команду список файлов с разделителем #13#10 или #0
Если что-то не понятно... бросай это дело


 
delpher_gray ©   (2003-09-18 14:22) [5]

2Verg:
TServer - это класс самого сервера ! Программа консольного типа...

2Slym:
Пасиба за подсказку !
Но в этом есть такое западло...
Например я послал команду с клиенда этуму серверу типа:
FILE LOAD file="c:\file.zip"#0
Сервер сразу же мне перешлёт файл, а как мне отделить этот файл от других команд ? Как узнать что это именно файл ??


 
Карелин Артем ©   (2003-09-18 14:41) [6]

Сигнатуру заведи или передавай файлы в отдельном коннекте.


 
Verg ©   (2003-09-18 16:44) [7]


> TServer - это класс самого сервера ! Программа консольного
> типа...


Я все понимаю.
Но кто (что) обрабатывает события у ServerSocket1?
Где назначения обработчиков?

Где, в конце концов, ServerClass:=TServer.Create?


 
delpher_gray ©   (2003-09-18 16:59) [8]

2Verg:
Правильно ! Забыл написать :))

----------

Плиз подскажите как разделять команды, если использовать пример протокола Slym"а ?


 
Digitman ©   (2003-09-18 17:31) [9]


> delpher_gray


с протоколом Slym"a тебе придется лексер/парсер реализовывать
дурацкая, думаю, доп.работа ради десятка "языковых" конструкций

кодируй разделы и команды в разделах неким числовым идентификатором строго опред.типа, например, Word

тогда при приеме кодов разделов и команд ты будешь ожидать строго определенное число байт (при Word - 2 байта)

пусть
FILE = 1
CMD = 2
SHELL = 3

пусть
LOAD = 1
UPLOAD = 2
DIR = 3
LIST = 4

тогда на принимающей стороне

case Section of
1: ... речь идет о файловых операциях
2: ... спец.команды
3: ... обращение к оболочке
end;

и т.д. и т.п.


 
delpher_gray ©   (2003-09-18 20:04) [10]

2Digitman:
Насколько я понял, нужно сделать так: от клиента принимать команды типа: "01C:\file.exe"#0 (что означает скачивание файла),
затем сервер посылает команду: "01C:\file.exe"#0"1024"#0 (команда на приём файла, размером 1024 байт).

После такого обмена информацией, клиент переводится в режим приёма файла, и записывает все принятые данные в MemoryStream, пока размер MS не будет равен 1024 байта... Если принялся весь файл, то клинт сохраняет файл, и снова переводится в режим приёма команд...

Правильно так ?

Я раньше использовал метод на подобии этого, и с ним у меня были ошибки ! Иногда файл не докачивался, иногда в коде файла были ошибки, иногда пакеты скелеивались, и клиент не мог отделить файл от команды и т.п. ерунда...

Подскажите как принимать и передавать данные такого типа без ошибок !?

Заранее благодарен.


 
$hade ©   (2003-09-19 06:43) [11]

Иногда файл не докачивался, иногда в коде файла были ошибки

насколько я знаю - TCP - портокол с гарантированой доставкой пакетов - если ты читаешь 1024 - то 1024 тебе и придет и именно те которые ты посылал...

а если пакеты склеиваются - все таки это ошибки в твоем коде а не в протоколе....

поиши в сети описание протокола ICQ...если убрать всю лишнюю замутность - вполне неплохой протокол...как раз тебе подойдет...


 
Verg ©   (2003-09-19 07:37) [12]


> Плиз подскажите как разделять команды, если использовать
> пример протокола Slym"а ?


Какие проблемы?
В ASCII ориентированных протоколах разделителями обычно является ВКПС (#13#10, \n)

Короче я так ине понял к чему был приведен код программы, при том заведомо неработающей, да еще и свопросом "Как чтобы она надежно работала?"

Для начала сделайте, чтобы она работала хотя бы ненадежно :), а там посмотрим.


 
Verg ©   (2003-09-19 07:47) [13]


> Подскажите как принимать и передавать данные такого типа
> без ошибок !?


Вы что-то себе надумываете.
Какие ошибки имеются ввиду?
Искажения символов? Или exception-ы типа Access violation ?

Против первого типа применяется CRC (контрольная сумма)+Избыточное кодирование (коды Хемминга или Боуза-Чохвингема-Ховисайда, блин, наверняка неправильно всмпомнил) если уж вы прониклись таким недоверием к TCP/IP.

Как тут не вспомнить анекдот про старую деву, свечку и презерватив.


 
Digitman ©   (2003-09-19 08:09) [14]


> delpher_gray


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


 
Verg ©   (2003-09-19 08:15) [15]


> при этом не используешь событие OnWrite, то проблемы твои
> именно от этого возникают


Пора бы это в ЧаВо или перед входом в форум-сети повесит :)


 
Digitman ©   (2003-09-19 08:32) [16]


> Verg


угу ... давно пора)


 
Slym ©   (2003-09-19 10:05) [17]

Ну если боишься файл не докачать...
Делай типа как в POP3/smtp, там конец письма #13#10+"."+#13#10

UPLOAD file="c:\autoexec.bat";eof="#13#10.#13#10"

качай файл пока не встретишь комбинацию eof...
если файлы бинарные, то надо бы eof генерить для КАЖДОГО файла!
Например GUID,но проверять на вхождение этой строки в файл!


 
Slym ©   (2003-09-19 10:06) [18]

А вообще как телнет работает... скока сказали принять столько и примет... все остальное ошибки юзера!


 
delpher_gray ©   (2003-09-19 11:13) [19]

Ммммм да....
Видно глюки из-за события OnWrite...
Я толком так и не понял как с ним мозно передать файл со 100% гарантией :)


 
delpher_gray ©   (2003-09-19 11:40) [20]

OnWrite тут по моему ни причём, ведь это событие возникает сразу после соединения, и только один раз за весь сеанс соединения !!
А я перед передачей MemoryStream"а, передавал и текстовые команды и они работали....


 
Verg ©   (2003-09-19 11:41) [21]


> Видно глюки из-за события OnWrite...


Бывает.

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

Между тем, начинать чего либо передавать в сокет после коннекта можно по только по условиям:
Для сервера : OnClientConnect && OnAccept && OnClientWrite
Для клиента : OnConnect && OnWrite

Мало того, при передаче данных (sendbuf) нужно анализировать рез-ат этой функции и если она вернула SOCKET_ERROR, а WSAGETLASTERROR = WSAEWOUDBLOCK, эту порцию информации надо сохранить и передавать только по наступлению следующего OnWrite.

А то напишут в OnConnect-е

Socket.SendText(S1);
Socket.SendText(S2);
Socket.SendText(S3);
Socket.SendText(S4);
Socket.SendText(S5);
.......
Socket.SendText(Sn);

А протом спрашивают: Почему глючит?

Тем не менее

function TCustomWinSocket.SendText(const s: string): Integer;
begin
Result := SendBuf(Pointer(S)^, Length(S));
end;


Получается сразу две ошибки!


 
delpher_gray ©   (2003-09-19 12:13) [22]

А можно конкретный пример работы OnWrite ?


 
Verg ©   (2003-09-19 13:19) [23]


> А можно конкретный пример работы OnWrite ?


См. исходники

function TCustomWinSocket.SendStream(AStream: TStream): Boolean;

C:\Program Files\Borland\Delphi6\Source\Vcl\ScktComp.pas

Вникните.

Потом могу дать вот такие два куска:


function TBridge.SendData(var Buffer; Size : integer):integer;
var Bptr : pChar;
Sends : integer;
S : string;
begin
BPtr := pchar(@Buffer);
Result:=1; Sends:=0;
if Pending="" then
begin
while (Result>0) and (Sends<Size) do
begin
result:=ClientSocket1.Socket.SendBuf((Bptr+Sends)^,Size-Sends);
if Result>=0 then inc(Sends,Result);
end;
if Result=SOCKET_ERROR then
begin
if WSAGetLastError=WSAEWOULDBLOCK then
SetString(Pending, Bptr+Sends, Size-Sends);
end else begin result:=Sends; Pending:=""; end;
end else
begin
SetString(S, Bptr, Size);
Pending:=Pending+S;
Result:=0;
end;
end;

procedure TBridge.ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
var S : string;
begin
if Pending<>"" then
begin
S:=Pending;
Pending:="";
SendData(Pchar(@S[1])^, length(S));
end;
end;



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

Текущий архив: 2003.11.13;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.032 c
3-40801
Михаил
2003-10-22 14:47
2003.11.13
При открытие запроса в сервисе WinNT ошибка. Не могу получить дан


1-41242
MaxwellZ
2003-10-31 23:43
2003.11.13
Выбрать директорию


3-40829
MagMag
2003-10-25 15:02
2003.11.13
Проверка регистрации пользователя


3-41043
Tumcoat
2003-10-14 08:52
2003.11.13
Физическое удаление записей


6-41822
Rodin
2003-09-11 11:15
2003.11.13
ip by name