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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.034 c
1-41471
Delphi5.01
2003-10-27 17:56
2003.11.13
Ошибка принтера


3-40830
geg
2003-10-22 09:25
2003.11.13
IBQuery1 filds то F_1 to SUM


3-40798
Виталя
2003-10-22 15:17
2003.11.13
Как отследить поле NULL возвращаемое хранимой процедурой ?


14-42040
Vlad Oshin
2003-10-16 11:58
2003.11.13
Ищу распозванулку рукописного текста, есть где-то?


1-41316
Anonim-777
2003-10-30 23:01
2003.11.13
Из initialization





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский