![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Размер передаваемых данных через сокеты [D6, WinXP]
psa247 © (2006-10-06 17:34:00)Добрый день !
Проблема такая:
Есть клиент, есть сервер.
Через сокет сервера передаю с помощью MemoryStream XML-файл. При передаче
ServerForm.Server.Socket.Connections[0].SendStreamThenDrop(srcfile) - результат True
На клиентской стороне большие файлы полностью не приходят.
События:
procedure Send_File(Sock : TCustomWinSocket; testname : string);
var srcfile: TMemoryStream;
fname : string;
p : pointer;
count, n : integer;
buffer: array [0..MAX_BUF_SIZE] of Char;
begin
fname:= Ini.ReadString('Tests',testname,'');
if fname='' then begin
Log('no such test '+ testname);
Send_Reply(Sock, 'no such test '+ testname);
exit;
end;
if not(FileExists(fname))then begin
Log(fname +'- not exists');
Send_Reply(Sock, fname +'- not exists');
exit;
end;
try
srcfile:= TMemoryStream.Create;
srcfile.LoadFromFile(fname);
count:= srcfile.size;
Log('Send: '+fname+ ' to '+ Sock.RemoteHost);
Log('filesize: '+ IntToStr(count) + ' byte');
n:= 0;
if ServerForm.Server.Socket.Connections[0].SendStreamThenDrop(srcfile)then Log(fname + ' - send successfully');
except
end;
end;
Клиент:
procedure TClientForm.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var str : widestring;
tmp_Res : TPars_Res;
count : integer;
buffer: array [0..MAX_BUF_SIZE] of Char;
begin
fStream.Position:= 0;
repeat
count:= Socket.ReceiveBuf(buffer,SizeOf(buffer));
if count > 0 then fStream.Read(buffer,MAX_BUF_SIZE);
str:= str + buffer;
Log('Reseived ' +IntToStr(count)+ ' byte');
MemoLog.Lines.Add(buffer);
until(count <= 0);
Log('Total: ' +IntToStr(fStream.Size)+ ' byte');
// XMLDocument1.LoadFromStream(fStream);
// fStream.SaveToFile('fill.fil');
...
Client.Close;
end;
psa247 (2006-10-10 09:11:00) [1]Благодарю за пояснение
Сергей М. (2006-10-09 08:21:00) [2]
> смысл события Server.Accept
Accept есть факт подтверждения сервером запроса клиента на подключение с созданием соответствующей вирт.петли соединения с этим клиентом.
> дать понять, что он не Accept
Он ужеaccept.
> чтобы он разорвал соединение самостоятельно
.. ему нужно послать некое предопределенное инф.сообщение, по получению которого клиент в соответствии с этим сообщением обязан разорвать соединение.
psa247 (2006-10-08 16:42:00) [3]Прошу пояснить смысл события Server.Accept и как клиенту дать понять, что он не Accept :), чтобы он разорвал соединение самостоятельно
medved_68 (2006-10-07 14:16:00) [4]psa247Если уж на клиенте используешь сокетный поток, то почему бы не использовать WaitForDataдля ожидания доставки, а затем читать в буфер определенной длинныи сливать в отдельный поток данные из буфера именно столько сколько вернет процедура чтения из сокетного потока, например:
//Принимаем данные
CapturePotok.Clear;
repeat
Readed:=FSocketPotok.Read(FReciveBuffer[0],8192);
if Readed>0 then
CapturePotok.WriteBuffer(FReciveBuffer[0],Readed);
где FSocketPotokпоток связанный с сокетом, а CapturePotok- поток для принятых данных. Тогда выход из цикла чтения repeatбудет если until Readed<=0;:))))
Ketmar (2006-10-06 18:44:00) [5]для начала -- пояснить, что есть ClientRead() и откуда его зовут.
psa247 (2006-10-06 18:39:00) [6]
> Ketmar
Что ты предлагаешь ?
psa247 (2006-10-06 18:32:00) [7]У меня асинхронные сокеты. Соответственно, ReceiveBuf возвратит значение, которое прочитал сервер, так ?
Ketmar (2006-10-06 18:32:00) [8]а мне вообще не ясно, зачем при подобном подходе использовать TCustomWinSocket. %-)
Ketmar (2006-10-06 18:32:00) [9]>[7] psa247(c) 6-Oct-2006, 18:32
>У меня асинхронные сокеты. Соответственно, ReceiveBuf
>возвратит значение, которое прочитал сервер, так ?
читаем [5] до полного просветления.
Verg (2006-10-06 18:29:00) [10]Кроме всего ..
Если пришел чистый FD_CLOSE (OnClose), то, тем не менее, необходимо "вычитать" все данные из соединения, если они там имеются
см. MSDN про WSAASyncSelect
Ketmar (2006-10-06 18:20:00) [11]ReceiveBuf only works in response to a read notification to a non-blocking windows socket. Blocking sockets must use a TWinSocketStream for reading.
psa247 (2006-10-06 18:08:00) [12]Если правильно понял, то
ReceiveBuf(buffer,SizeOf(buffer)); возвращает количество полученных байт
?
Ketmar (2006-10-06 18:04:00) [13]так вот я тихо намекаю, что в вышеприведённом бреде никакими "count" и не пахнет...
psa247 (2006-10-06 18:03:00) [14]Делаю по схеме:
получил определенное кол-во байт, записал в память, отобразил в лог для контроля, только там fstream.Read(buffer, count)
Ketmar (2006-10-06 17:54:00) [15]>[0] psa247(c) 6-Oct-2006, 17:34
> if count > 0 then fStream.Read(buffer,MAX_BUF_SIZE);
это что за бред?
> MemoLog.Lines.Add(buffer);
а это что за бред?