![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сокеты [D6, Win2k]
Freedom © (2005-01-08 22:24:00)Здравствуйте!
Используя коспоненты ClientSocket и ServerSocket,реализовал две программы Клиент и Сервер.Две программы могут передавать друг другу сообщения и передавать файлы.Возникла проблема в передачи файла.Файлы передаю через ClientSocket1.Socket.SendStream(TFileStream.Create(filename,fmOpenRead or fmShareDenyWrite));
На сервере имеется обрабработчик onread, который принимает как текстовые сообщения так и файлы.Выглядит это так:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var ilen,z: Integer;
buf: Pointer;
begin
//прием текстового сообщения
if (Socket.ReceiveText<>'send') and (not flag) then
begin
ListBox1.Items.Add('Client: '+Socket.ReceiveText);
for z := 0 to ServerSocket1.Socket.ActiveConnections-1 do ServerSocket1.Socket.Connections[z].SendText('Client: '+Socket.ReceiveText);
// прием файла
end
else
if flag then
begin
{Открываем временный файл для записи}
FStream := TFileStream.Create('myfile.tmp',fmCreate or fmShareDenyWrite);
{Записываем в l размер полученного блока}
ilen := Socket.ReceiveLength;
{Заказываем память для буфера}
GetMem(buf,ilen);
{Записываем в буфер полученный блок}
Socket.ReceiveBuf(buf^,ilen);
{Ставим позицию в конец файла}
try
Socket.ReceiveBuf(Buf^, iLen);
FStream.Write(Buf^, iLen);
finally
FreeMem(Buf);
end;
ListenFileEdit.Text:='Получен файл';
end
else
begin
flag:=true;
exit;
end;
end;
Текстовые сообщения принимает отлично,а вот файл получается пустым.Если переставить код принятие файла до приема простых сообщений,то все отлично.
Посоветуйте пожалуйства,что делать.
Не охото вставлять второй компонент на форму.
xman (2005-01-13 16:32:00) [1]Кто то может скинуть ссылочку на
код программы (пример)
передачи файлов по сети (по локалке)
с использованием сокетов (Client/serverSocket компонентов)
Eraser (2005-01-12 15:20:00) [2]>> Verg
Согласен! Про отсутствие многозадачности (поддрежки механизмов ;)) в TClient/ServerSocket это я погорячился, я перепутал с сетевыми компонентами из 6 версии делфей. Признаю.
Indy - пакет по-своему хорош, но это не дает право приписывать другим "пакетам" несуществующие недостатки. Тем более, что "ноги растут" у всех них из winsock (Berkeley соместимая часть). В результате используется только половина мощности API WIN32. Вокруг этого в Indy очень много чего лишнего нверчено. Осознанно выбран путь совместимости в ущерб эффективности.
Те вещи, котрые нельзя реализовать в Indy, нужно реализовывать на чистом API- полностью согласен! Но все эти надстройки над TCP (которые отличают чистые сокеты от winsock) имеют чисто прикладной характер, не факт, что в следующих версиях винды их вообще не снесут... А pure Berkeley socket и есть сокет, в ближайшие годы он никуда не денеться. Тем более что в Indy 10 встроена поддержка IPv6.
BiN (2005-01-12 15:14:00) [3]Eraser © (12.01.05 13:06) [27]
Вспоминается сразу фраза про пинание зеркала и кривую рожу... :)
Verg (2005-01-12 15:03:00) [4]
> Eraser © (12.01.05 13:06) [27]
И все же. Вы до сих пор утверждали ([1]), что в TClient/ServerSocket "отсутствует многозадачность". Это до сих пор в силе как утверждение?
Indy - пакет по-своему хорош, но это не дает право приписывать другим "пакетам" несуществующие недостатки. Тем более, что "ноги растут" у всех них из winsock (Berkeley соместимая часть). В результате используется только половина мощности API WIN32. Вокруг этого в Indy очень много чего лишнего нверчено. Осознанно выбран путь совместимости в ущерб эффективности.
> PS Я так рьяно защищаю Indy, только потому, что у меня есть
> горький опыт использования других компонентов и winsock-
> у всех них одна беда- проблема с расширяемостью. Например,
> такая мелочь, как включение поддержки SOCKS серверов в приложение,
> при использовании TServer/ClientSocket выливается в огромную
> проблему (всё приходиться писать ручками), я уже не говорю
> про чистый winsock API.
Есть примеры "горького опыта" неверного (неграмотного) использования и Indy.
Такого сорта неграмотность (недостаток опыта) тоже говорит о том, что на Indy "надо забить"?
Или мы сейчас рассуждаем исключительно про Ваш личный опыт?
Eraser (2005-01-12 13:06:00) [5]эти надстройки с легкостьюреализуются
Незнаю насчет лёгкости, ну ка реализуй клиенты pop3, SOCKS, portmapping, smtp и т.д. не говоря уже о серверах этих протоколов. У тебя может это и получится, у меня- сомневаюсь, по крайней мере на это уйдёт куча времени (включая досканальное изучение RFC и, главное, отладку)
.
любой "серьезный" проект подразумевает среди прочего сведение к минимуму избыточности кода
полностью согласен!- чем меньше самописного кода, тем меньше вероятность возникновения глюков, но тут уж нельзя не согласиться, что при использовании Indy код будет меньше (ни или такой же), как при TServer/ClientSocket.
которые являют собой компоненты исключительно прикладного транспортного уровня и которые "заточены" именно под Win32
Тут в защиту Indy могу сказть, что если компилируешь проект под Win32, то он использует абсолютно те же API (без сторонних библиотек) что и TServer/ClientSocket. Это обеспечивается наличием дирректив IFDEF-ENDIF в коде ИНДИ. Что касается CLX, то на сколько я знаю в 10 версии она уже (или до сих пор (не сталкивался)) не поддерживается, зато поддерживается .NET, что позволяет легко портировать приложения, написанные даже на Delphi7 в .NET.
PS Я так рьяно защищаю Indy, только потому, что у меня есть горький опыт использования других компонентов и winsock- у всех них одна беда- проблема с расширяемостью. Например, такая мелочь, как включение поддержки SOCKS серверов в приложение, при использовании TServer/ClientSocket выливается в огромную проблему (всё приходиться писать ручками), я уже не говорю про чистый winsock API.
Digitman (2005-01-12 08:31:00) [6]
> Eraser © (12.01.05 01:52) [25]
> использовании этих компонентов для построения серьёзных
> проектов
любой "серьезный" проект подразумевает среди прочего сведение к минимуму избыточности кода
Инди же по задумке разработчиков претендует на некую "универсальность", связанную как минимум с кросплатформенностью .. а любая "универсальность" кода ведет к его избыточности ..
Кр.того, "поддержка протоколов высокого уровня" (точнее - прикладных протоколов) есть не более чем надстройки над протоколами транспортного уровня (см. модель OSI), и эти надстройки с легкостью реализуются и на базе тех же TServer/ClientSocket, которые являют собой компоненты исключительно прикладного транспортного уровня и которые "заточены" именно под Win32
Eraser (2005-01-12 01:52:00) [7]>> Digitman
Я не говорил, что TClientSocket и TServerSocket не поддерживает дескрипторы.
галиматьяне придирайся к словам ;-))
Я советую (!не рекламирую!-мне за это не платят) Indy по пречине понятности и удобства в использовании этих компонентов для построения серьёзных проектов и их дальнейшего развития. Это я о поддержке протоколов высокого уровня (http, ftp, dns, .. etc.) и о встроеннойсистеме шифровани и сжатия (Indy10).
Digitman (2005-01-11 13:19:00) [8]
> VMcL © (10.01.05 06:46) [12]
)
> Eraser © (10.01.05 19:58) [23]
см. [12]
плинтус там иль не плинтус, но каша в твоей светлой голове заметна невооруженным глазом
прокомментирую, дабы не быть голословным ..
> Indy предоставляет дескрипторы
св-во TCustomWinSocket.SocketHandle и есть точь-в-точь тот же самый "дескриптор", которым ты размахиваешь аки жупелом, "рекламируя" Инди.
> по причине отсутствия многозадачности
галиматья.
термин "многозадачность" и механизм, подразумеваемый под оным термином, применим лишь на уровне ОС, которая в нашем случае по дифолту "многозадачна"
если же таки подразумевалась некая "многопоточность" некоего алгоритма, реализуемого некоей задачей, то см. [16]
Eraser (2005-01-10 19:58:00) [9]Verg ©
И чем же я ввожу в заблуждение?
Ещё раз повторюсь- на TClientSocket и TServerSocket не построишь серьёзного приложения. Это моё личное мнение.
Verg (2005-01-10 16:05:00) [10]
> Кстати, а если информацию не извлечь в OnRead, она сохранится
> в следующих OnRead'ах - или буфер каждый раз затирается?
Если речь про асинхронный режим, то
Если не извлечь совсем (ни одного октета, ниразу не вызвать recv), то OnRead больше вообще не возникнет.
Условия возникновения (установки сообщения в очередь соотв. окна) OnRead по ИЛИ:
1. С транспортного уровня поступила порция инфрормации (неважно какого размера<>0), а приемный буфер пуст.
2. Вызвали ф-цию recv, но после нее в приемном буфере осталась информация (прочитали меньше, чем там есть).
Sapersky (2005-01-10 15:52:00) [11]Как мне показалось, ты не понимаешь, что эти ф-ции извлекают (безвозвратно) информацию из приемного буфера сокета.
Кстати, а если информацию не извлечь в OnRead, она сохранится в следующих OnRead'ах - или буфер каждый раз затирается?
Verg (2005-01-10 15:16:00) [12]
> [19] Eraser © (10.01.05 15:06)
На вкус и цвет - нет, но речь идет о достаточно точной науке и мне кажется, что Вы своими утверждениями вводите в заблуждения, в которых находитесь сами.
Eraser (2005-01-10 15:06:00) [13]->>> Verg
На вкус и цвет друзей нету ;-))
Verg (2005-01-10 15:04:00) [14]
> [17] Eraser © (10.01.05 15:03)
см. [16]
Eraser (2005-01-10 15:03:00) [15]см. [13], [14]
Verg (2005-01-10 14:59:00) [16]
> 1] Eraser © (09.01.05 00:12)
> Используй Indy, и забей на ClientSocket и ServerSocket,
> на них ничего серьёзного не сделаешь, по причине отсутствия
> многозадачности.
Режим TServerSocket-а stThreadBlocking - это как, пустой звук что ли?
> [10] Eraser © (10.01.05 00:43)
> kaZaNoVa
> Спору нет )) Indy на API и написаны! Просто делать серьёзный
> сервер на API это почти тоже самое, что делать приложение
> Win32 на ассмеблере, можно, но не очень просто...
> Хотя в некоторых случаях без API не обойтись. Но Indy предоставляет
> дескрипторы!
А что непредоставляет дескрипторов? Win32 API или что?
Verg (2005-01-10 14:42:00) [17]
> Freedom (08.01.05 22:24)
Проблема очевидна.
1. За одно событие OnRead несколько раз вызываешь Receive*** ф-ции. Как мне показалось, ты не понимаешь, что эти ф-ции извлекают(безвозвратно) информацию из приемного буфера сокета.
2. ReceiveLength возвращает "приблизительный" объем принятой порции (см. help по этой ф-ции). Результат можно использовать для предсказания необходимого размера буфера, но не для определения кол-ва принятой информации. Точный размер вернет толькоReceiveBuf.
Eraser (2005-01-10 14:10:00) [18]>>Alexander Panov
Именно из собственного опыта ( http://aledensoft.com/).
Сначала пытался писать на API, но возник ряд проблем с многопоточностью, короче моё приложение не такого масштаба, чтобы тратить время на разработку и главное ОТЛАДКУсобтвенного TCP многопоточного сервера.
Сейчас (с выходом 10 версии) моё мнение поменялось ещё более координально, я считаю что даже серьёзные приложения стоит писать на Indy.
см [13].
Eraser (2005-01-10 14:04:00) [19]>>VMcL
Я не говорил что TClientSocket и TServerSocket не используют API (Windows Sockets API, если ты не знаешь ;)), просто Indy гораздо удобнее использовать, и у них (него) более грамотная архетектура, он совместим с dotNet (10 версия) и уже содержит кучу отлаженных компонентов для работы с прикладными протоколами.
Конечно дело вкуса, но ИМХО имеет смысл использовать либо Indy, либо чистый API.
VMcL (2005-01-10 06:46:00) [20]>> Eraser © (09.01.05 00:12) [1]
> забей на ClientSocket и ServerSocket, на них ничего серьёзного не сделаешь, по причине отсутствия многозадачности.
Не пишите чушь. Потому что придёт злой Цифровой человек и опустит ниже плинтуса.
P.S. Object Inspector'ом не пробовали пользоваться? Свойство ServerType у TServerSocket'а ненароком не видели?
>> Eraser © (10.01.05 00:43) [10]
> Indy на API и написаны!
Во-первых, на API не пишут. API используют. Во-вторых, не стоит так громко кричать - не в "Потрепаться". Во-третьих, который именно API, неясно. WinAPI что ли? А TClientSocket и TServerSocket, стало быть, не WinAPI используют?