Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Может кто подскажет


AndOrXor ©   (2002-09-10 09:11:00) 

Отправляю данные с клиента (TClientSocket) на сервер (TServerSocket). Ланные больших размеров - 100Мб. Если на одной машине, то все нормально передается. Сервер перенашу на другую машину и сного отправляю. Все валится. На маленьких размерах нормально работает. Не могу разобраться в чем глюк. Если ставлю принемать с breakpoint-м, то все нормально приходит. 8(


VID   (2002-09-10 16:17:00) [1]

to AndOrXor: вообще я тоже для каждого клиента в своём сервере создаю TClientDataObj с поляим ReceivedPacket и SocketHandle...
Только вот C я не знаю...


cyborg   (2002-09-10 11:08:00) [2]

Можно спросить?
Что, Си-шные сайты "Атцтой", раз вы сюда это пишите?


AndOrXor   (2002-09-10 10:13:00) [3]

эээ, достаточно сложно будет разобраться. Сильно намутил 8) Мне кажется что можно и попроще сделать. Буду очень рад, если подскажете как сделать.
Короче, для каждого приконнектившегося пользователя создается новый объект класса TClientDesc, он умеет хранить принятые данные конкретного пользователя и в нем хранится сокет-хэндл пользователя. Данные хранятся в так называемом пакете. У каждого пользователя из может быть сколько угодно. Для каждого пользователя образуется список принятых пакетов. У пакета есть заголовок с описанием. Первые 4 байта - длина пакета.

//Reciev на сервере
void __fastcall TSSocket::Receive(TObject *Sender,TCustomWinSocket *Socket)
{
bool bRunHandler = false; //разрешение на запуск обработчика принятых данных

TClientDesc* pUser = HandleToUser(Socket->SocketHandle); //по хэндэлу сокета получаем указатель на пользователя

if (pUser == NULL)
{
GO()->Log->Error("Soc: Ошибка сервера");
return;
}

void * pdBuffer = new(char[Socket->ReceiveLength()]); //формируем буфер для пришедших данных

int iActualBytesReceived = Socket->ReceiveBuf(pdBuffer, Socket->ReceiveLength()); //копируем пришедшие данные в буфер

if(iActualBytesReceived == -1) return;

int iOffSet = 0;

do
{
int iFull = pUser->LenCurrent + iActualBytesReceived; //если последний пакет пришел полностью, то LenCurrent вернет 0, иначе колличество байт которые уже записаны

if(!pUser->LenCommon) //Если до этого все данные были приняты полностью, то LenCommon = 0, иначе длину последнего недозаписанного пакета
{
pUser->LenCommon = *(int*)((char*)pdBuffer+iOffSet); //получаем длину нового пакета (тут я делую опущение, что пришло >= 4 байт
}

TPacket *pPacket = pUser->Current; //получаем указатель на последний пакет, если до этого пришли все данные то возвращается указатель на новый пакет

if(pUser->LenCommon LenCommon - pUser->LenCurrent; //Высчитываем разницу сколько необходимо дозаписать

pPacket->WritePacket((char*)pdBuffer+iOffSet,iRemainder);//дозаписываем в пакет найденную разницу

iOffSet += iRemainder; //делаем смешение на колличество дозаписанных данных

iActualBytesReceived -= iRemainder; // вычитаем из колличиства принятых длину куска которую мы записали

//пакет дозаписан, сбрасываем общую длину и последню записанныу длину в 0
pUser->LenCommon = 0; //
pUser->LenCurrent = 0;
//данные приняты, разрешем их обработку
bRunHandler = true;
}
else
{
//если данных (которые уже записаны в пакет + которые пришли) пришло меньше чем длина пакета, то их просто дозаписываем
pPacket->WritePacket((char*)pdBuffer+iOffSet,iActualBytesReceived);

pUser->LenCurrent = iFull;

iActualBytesReceived = 0;
}
}while(iActualBytesReceived);

delete pdBuffer;


if (bRunHandler && !pUser->Run) //Если разрешен запуск обработчиков и никакой из обработчиков в данный момент не запущен
{
pUser->Run = true; //ставим флаг что обработчик запущен

while(!pUser->Border) //Перебираем все пакеты которые стоят в очереди на обрабоку до граничного
{
TPacket *pPacket = pUser->Items;

try
{
NMOwner->FilterOfPackages(pPacket, this, Socket->SocketHandle); //запускаем обработчик
}
catch (...)
{
GO()->Log->InternalError("обработчик не найден " + IntToStr(pPacket->ToHandlerID));

delete pPacket;
}

delete pPacket;
}

pUser->Run = false;
}
}


VID   (2002-09-10 09:40:00) [4]


> Все валится


Сервер выгружается из ОЗУ ? Или клиент ? BreakPoints для сервера или для клиента ?

Код ServerOnClientRead, ServerOnClientError, ClientOnError, ServerOnClientDisconnect, ClientOnDisconnect - неплохо было б посмотреть что там...
а так же код, где реализуется отправка данных от клиента к серверу.


Наверх

Титульная страница Поиск, карта сайта Написать письмо