void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
{int intbuffer,cmd,i;
bool boolbuffer;
wchar_t* charbuffer;
TIniFile* timetable;
TMemoryStream* msg=new TMemoryStream();
AContext->Connection->IOHandler->ReadStream(msg,sizeof(int)*2,false);
msg->Position=0;
msg->Seek(0,0);
msg->Read(&cmd,sizeof(int));
switch(cmd)
{
case 1: // Авторизация
{
srand(::GetTickCount());
msg->Read(&intbuffer,sizeof(int));
delete msg;
msg=new TMemoryStream();
charbuffer=new wchar_t [intbuffer];
AContext->Connection->IOHandler->ReadStream(msg,sizeof(wchar_t)*intbuffer,false);
msg->Position=0;
msg->Seek(0,0);
msg->Read(&charbuffer,sizeof(wchar_t)*intbuffer);
// Сверяем пароль
// Пользователь
if(UnicodeString(charbuffer).SubString(1,intbuffer)==(UnicodeString(ServerPassword[0])))
{
delete msg;
msg=new TMemoryStream();
intbuffer=1;
msg->Write(&intbuffer,sizeof(int));
intbuffer=rand()+1;
msg->Write(&intbuffer,sizeof(int));
this->AddUserHandle(intbuffer);
this->Memo1->Lines->Add(Now().DateTimeString()+" Peer connected as User with handle "+IntToStr(intbuffer));
msg->Position=0;
msg->Seek(0,0);
AContext->Connection->IOHandler->Write(msg,msg->Size,false);
intbuffer=2;
AContext->Connection->Disconnect();
}
// Наблюдатель
else if (UnicodeString(charbuffer).SubString(1,intbuffer)==(UnicodeString(ServerPassword[1])))
{
// Здесь не бываем
}
delete [] charbuffer;
break;
}
Connection Closed Gracefully. Indy 10.
При работе в режиме отладки и при запускании приложении в режиме отладки никаких проблем нет.
Стоит запустить приложение в режиме "Release", так сразу валятся исключения "Connection Closed Gracefully". Все бы ничего, если бы не тот факт, что сервер, собственно не закрывает соединение, то есть в логе это не отображается (хотя в режиме дебагинга все работает как часы). А закрытие соединения со стороны сервера идет только после оставления записи в логе. Значит проблема в клиенте, но там тоже ошибок не наблюдается (комментировал с обоих сторон закрытие соединения, все равно та же проблема), но соединение успешно (ли) рвется в одном и том же месте. Дебаггером пройтись не удается, ибо с ним все работает как часы.
Пробовал отключать какую-либо оптимизацию кода, исход один. Соединение закрывается успешно, хотя до этого момента в логике программы еще далеко. Таймауты сервера и клиента выкручены до запредельных высот, но соединение рвется меньше чем за секунду. В чем проблема, понять выше моих сил.
Самое интересное, эта ошибка появляется только при модификации уже работающего кода (код мой, и работает по схожему принципу, а модификация проходит в диаметрально противоположных направлениях, то есть в другой части кода, работа с интерфейсом, например).
Проблемный код у сервера и у клиента:
сервер
Код:
клиент
Код:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(!this->Connected)
{
int intbuffer;
// Определяем параметры соединения
this->IdTCPClient1->Port=this->Edit2->Text.ToInt();
this->IdTCPClient1->Host=this->Edit1->Text;
// Создаем поток данных для передачи
TMemoryStream* msg=new TMemoryStream();
intbuffer=1;
msg->Write(&intbuffer,sizeof(int));
intbuffer=this->Edit3->Text.Length();
msg->Write(&intbuffer,sizeof(int));
msg->Write(this->Edit3->Text.w_str(),sizeof(wchar_t)*intbuffer);
// Передача данных
if(this->IdTCPClient1->Connected())
{
this->IdTCPClient1->Disconnect();
}
this->IdTCPClient1->Connect();
msg->Position=0;
msg->Seek(0,0);
this->IdTCPClient1->IOHandler->Write(msg,msg->Size,false);
delete msg;
msg=new TMemoryStream();
// Получение ответа
this->IdTCPClient1->IOHandler->ReadStream(msg,sizeof(int),false);
msg->Position=0;
msg->Seek(0,0);
msg->Read(&intbuffer,sizeof(int));
switch(intbuffer)
{
case 1: // Все хорошо, мы пользователи
{
delete msg;
msg=new TMemoryStream();
// Получение ответа
this->IdTCPClient1->IOHandler->ReadStream(msg,sizeof(int),false);
msg->Position=0;
msg->Seek(0,0);
msg->Read(&intbuffer,sizeof(int));
this->ConHandle=intbuffer;
this->Connected=1;
Application->MessageBoxW((wchar_t*)WideString("Доступ разрешен. Группа - пользователи."),(wchar_t*)WideString("Подключено"));
this->IdTCPClient1->Disconnect();
this->TabSheet2->TabVisible=true;
this->TabSheet3->TabVisible=true;
this->TabSheet4->TabVisible=true;
break;
}
case 2: // Все хорошо, мы наблюдатели
{
// Здесь нас нет
}
case 4: // Все хорошо, нас послали :)
{
// И здесь тоже
}
default: // Все плохо
{
// И тут
}
}
delete msg;
}
}
{
if(!this->Connected)
{
int intbuffer;
// Определяем параметры соединения
this->IdTCPClient1->Port=this->Edit2->Text.ToInt();
this->IdTCPClient1->Host=this->Edit1->Text;
// Создаем поток данных для передачи
TMemoryStream* msg=new TMemoryStream();
intbuffer=1;
msg->Write(&intbuffer,sizeof(int));
intbuffer=this->Edit3->Text.Length();
msg->Write(&intbuffer,sizeof(int));
msg->Write(this->Edit3->Text.w_str(),sizeof(wchar_t)*intbuffer);
// Передача данных
if(this->IdTCPClient1->Connected())
{
this->IdTCPClient1->Disconnect();
}
this->IdTCPClient1->Connect();
msg->Position=0;
msg->Seek(0,0);
this->IdTCPClient1->IOHandler->Write(msg,msg->Size,false);
delete msg;
msg=new TMemoryStream();
// Получение ответа
this->IdTCPClient1->IOHandler->ReadStream(msg,sizeof(int),false);
msg->Position=0;
msg->Seek(0,0);
msg->Read(&intbuffer,sizeof(int));
switch(intbuffer)
{
case 1: // Все хорошо, мы пользователи
{
delete msg;
msg=new TMemoryStream();
// Получение ответа
this->IdTCPClient1->IOHandler->ReadStream(msg,sizeof(int),false);
msg->Position=0;
msg->Seek(0,0);
msg->Read(&intbuffer,sizeof(int));
this->ConHandle=intbuffer;
this->Connected=1;
Application->MessageBoxW((wchar_t*)WideString("Доступ разрешен. Группа - пользователи."),(wchar_t*)WideString("Подключено"));
this->IdTCPClient1->Disconnect();
this->TabSheet2->TabVisible=true;
this->TabSheet3->TabVisible=true;
this->TabSheet4->TabVisible=true;
break;
}
case 2: // Все хорошо, мы наблюдатели
{
// Здесь нас нет
}
case 4: // Все хорошо, нас послали :)
{
// И здесь тоже
}
default: // Все плохо
{
// И тут
}
}
delete msg;
}
}
Исключение валится и при запуске уже откомпилированного экзешника, даже если из РАД он запускался без проблем (даже если не установлены брякпоинты в коде, он все равно отлично запускает из-под РАД, лишь бы запуск был с дебагом).
Блоки трай-кач в основном сипипишнике программы коментировал, но исключение все равно вываливается.
Схожая программа, на основе которой делается эта, работает без проблем в любой сборке, код в проблемном месте имеет абсолютно такой же. У кого-нибудь, может была проблема схожая?
Кто-нибудь может объяснить логику этого? Ладно, я готов поверить был в строчки до Дисконекта, но чтобы после... Как это возможно, если учитывать тот факт, что клиент не порвет соединение до того момента, пока не прочитает буффер от врайта до дисконекта?
Кто-либо здесь познал дзен и может общаться с инди?
Connection Closed Gracefully-не ошибка.Это значит что сервер,получил запрос,обработал и закрыл соединение.