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

Вниз

Подскажите как сделать   Найти похожие ветки 

 
Lexxt   (2002-04-18 13:38) [0]

На счет TServerSocket
Если информация поступает блоками, подскажите как ее собрать в памяти?


 
Song ©   (2002-04-18 13:57) [1]

В FAQ есть пример обмена данными, вот там как раз он собирается до кучи, потом сохраняется.

Если быть кратким, то используте TMemoryStream для накопления и проверяйте равен ли Postion Size"у.


 
Lexxt   (2002-04-18 14:22) [2]

void __fastcall TForm1::ssClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
pStream->Seek(0,soFromEnd);
int iLen=Socket->ReceiveLength();
pStream->SetSize(iLen+pStream->Size);
Socket->ReceiveBuf(pStream->Memory,iLen);
}

Если не сложно, подскажите где ошибка?


 
Digitman ©   (2002-04-18 15:09) [3]

1. почитай внимательно про ReceiveLength() - он работает не так, как ты ожидаешь.

2. Установка нового (большего) размера потока вовсе не гарантирует сохранность его содержимого, имевшегося до вызова setSize()


 
Lexxt   (2002-04-18 15:18) [4]

Согласен. Подскажи как правильно принять данные. Как-то же их все-таки принимают.


 
Digitman ©   (2002-04-18 17:24) [5]


procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
nActualBytesReceived: DWord;
pTempBuf: Pointer;
begin
GetMem(pTempBuf, Socket.ReceiveLength);
try
nActualBytesReceived := Socket.ReceiveBuf(pTempBuf^, Socket.ReceiveLength);
pStread.Write(pTempBuf^, nActualBytesReceived);
finally
FreeMem(pTempBuf);
end;
end;


 
Lexxt   (2002-04-18 21:30) [6]

Respect Digitman
Ктати, кого интересует на Builder-е

pStream=new TMemoryStream;
TMemoryStream *pStream;
..........
..........
void __fastcall TForm1::ssClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
void *pStrBuf;
double nActualBytesReceived;
pStrBuf=new(char[Socket->ReceiveLength()]);
nActualBytesReceived = Socket->ReceiveBuf(pStrBuf, Socket->ReceiveLength());
pStream->Write(pStrBuf,nActualBytesReceived);
}


 
Doom ©   (2002-04-18 22:46) [7]


> pStream=new TMemoryStream;
> TMemoryStream *pStream;

не наоборот?


 
Lexxt   (2002-04-18 23:25) [8]

да не, я их просто вставил, чтобы было понятно, что за pStream. Наоборот конечно.


 
Digitman ©   (2002-04-19 08:20) [9]

>Lexxt
А куда у тебя делось безусловное освобождение врем.буфера ?


 
Lexxt   (2002-04-19 11:38) [10]

Digitman, покажи плз на примере, как организовать подобную процедуру в
void __fastcall TServerThread::ClientExecute()
{

}


 
Lexxt   (2002-04-19 12:00) [11]

void __fastcall TServerThread::ClientExecute()
{
TMemoryStream *pMemStream = new TMemoryStream;
TWinSocketStream *pStream = new TWinSocketStream(ClientSocket, 20000);
void *pStrBuf;
double nActualBytesReceived;
try
{
while (!Terminated && ClientSocket->Connected)
{
pStrBuf=new(char[ClientSocket->ReceiveLength()]);
nActualBytesReceived = ClientSocket->ReceiveBuf(pStrBuf, ClientSocket->ReceiveLength());

if (nActualBytesReceived==0) break;

pStream->Write(pStrBuf,nActualBytesReceived);
delete pStrBuf;
}
}
__finally
{
delete pStream;
delete pMemStream;
ClientSocket->Close();
}
}
Я сделал вот так, но мне кажется это не совсем верное решение


 
Digitman ©   (2002-04-19 12:17) [12]

Примерно так :


procedure TMyServerClientTransportThread.ClientExecute;
var
FDSet: TFDSet;
TimeVal: TTimeVal;
nEstimatedBytesToReceive, nActualBytesReceived: DWord;
pTempBuf: Pointer;
begin
while not Terminated and ClientSocket.Connected do
begin
FD_ZERO(FDSet);
FD_SET(ClientSocket.SocketHandle, FDSet);
TimeVal.tv_sec := 0;
TimeVal.tv_usec := 500;
//если буфер приема гнезда не пуст
if (select(0, @FDSet, nil, nil, @TimeVal) > 0) and not Terminated then
try
//ожидаемый размер доступных данных в буфере приема гнезда
nEstimatedBytesToReceive:= ClientSocket.ReceiveBuf(FDSet, -1);
//если ожидаемый размер - ненулевой
if nEstimatedBytesToReceive > 0 then begin
//память под врем.буфер ожидаемого размера
GetMem(pTempBuf, nEstimatedBytesToReceive);
try
//попытка получить данные ожидаемого размера
nActualBytesReceived := ClientSocket.ReceiveBuf(pTempBuf^, nEstimatedBytesToReceive);
//в nActualBytesReceived - действительный размер
//полученных данных, м.б. меньше ожидаемого
//из-за особенностей работы TCP.
//Копировать содержимое врем.буфера в поток :
pStread.Write(pTempBuf^, nActualBytesReceived);
finally
//безусловно освободить память под врем.буфер
FreeMem(pTempBuf);
end;
end;
except
//возможные исключения безусловно должны быть "погашены"
end;
end;
end;


 
Lexxt   (2002-04-19 13:28) [13]

спасибо, я думаю это многим пригодится


 
Lexxt   (2002-04-19 13:42) [14]

Правда не совсем понятно, что представляет из себя
TFDSet,TTimeVal и select


 
Digitman ©   (2002-04-19 14:11) [15]

TFDSet = record
fd_count: u_int;
fd_array: array[0..FD_SETSIZE-1] of TSocket;
end;

PTimeVal = ^TTimeVal;
{$EXTERNALSYM timeval}
timeval = record
tv_sec: Longint;
tv_usec: Longint;
end;
TTimeVal = timeval;

см. Winsock.pas



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

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

Наверх




Память: 0.5 MB
Время: 0.019 c
14-89024
[NIKEL]
2002-05-26 22:22
2002.06.27
Исходники шашек или(лучше) Поддавки


8-88967
Aristotel
2002-02-15 20:51
2002.06.27
Как создать иконки на форме и при необходимости их перемещать?? Как на рабочем столе в Windows!


3-88730
Explorer
2002-06-03 15:09
2002.06.27
Процедуры в MSSQL 2000


14-89039
Злой, не скажу кто, причина известна
2002-05-26 11:26
2002.06.27
В мире полно лохов


1-88939
Sniffer
2002-06-15 14:13
2002.06.27
Как загрузить картинку из файла ресурсов