Форум: "Сети";
Текущий архив: 2002.06.27;
Скачать: [xml.tar.bz2];
ВнизПодскажите как сделать Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c