次のコードでは、すべてのクライアントに1秒間に2回メッセージを送信し、別のメッセージを1分間に8〜10回送信する単純なサーバーを使用しています。単純なIndyサーバーコードを使用したアクセス違反
アクセス違反で00479740読み出しアドレス
しかし、唯一の少数のシステムでFFFFFFD0、そして唯一の1または2回日:
問題は、私は、実行時にエラーを取得しています。このソフトウェアは1日に約10時間働きます。
私はICSライブラリで同様のコードを使用しようとしましたが、うまくいくようです。
このコードで何が問題になっていますか?それをコード化する良い方法はありますか?
void __fastcall TDataNet::DataModuleCreate(TObject *Sender)
{
listaClient= new TThreadList();
psTx= new TStringList();
psRx= new TStringList();
}
void __fastcall TDataNet::DataModuleDestroy(TObject *Sender)
{
IdTCPServer1->Active= false;
listaClient->Free();
delete psTx;
delete psRx;
}
void __fastcall TDataNet::Send(TStrings *ps, TIdContext *AContext)
{
TList *lista;
static int cntSend= 0;
try
{
lista= listaClient->LockList();
if(AContext != NULL)
{
AContext->Connection->IOHandler->Write(ps, true, TIdTextEncoding_UTF8);
}
else
{
for(int i=0; i < lista->Count; i++)
((TDatiClient*)lista->Items[i])->pThread->Connection->IOHandler->Write(ps, true, TIdTextEncoding_UTF8);
}
}
__finally
{
listaClient->UnlockList();
}
}
void __fastcall TDataNet::SetCambioPilota(void)
{
unsigned short hh, mm, ss, ms, hh1, mm1, ss1, ms1;
unsigned short hh2, mm2, ss2, ms2, hh3, mm3, ss3, ms3;
unsigned short hh4, mm4, ss4, ms4, dd4;
unsigned short hh5, mm5, ss5, ms5, dd5;
TStrings *ps;
UnicodeString s;
try
{
ps= psTx;
ps->Clear();
s= "<CAMBIO_PILOTA>";
ps->Add(s);
for(int i=0; i < MAX_PILOTI; i++)
{
s.sprintf(L"<Pilota%02x= I%x,\"A%s\",\"C%s\",\"F%s\",f%x>",
i+1, gara.pilota[i].idnome,
gara.pilota[i].nome.c_str(), gara.pilota[i].nick.c_str(),
gara.pilota[i].nomeTeam.c_str(), gara.pilota[i].idPilotaT);
ps->Add(s);
}
s= "<END_CAMBIO_PILOTA>";
ps->Add(s);
Send(ps);
}
catch(...){}
}
void __fastcall TDataNet::SetDatiGara(void)
{
TStrings *ps;
UnicodeString s;
try
{
ps= psTx;
ps->Clear();
s= "<DATI_GARA>";
ps->Add(s);
s.sprintf(L"<eve=%d,A%x,B%x,C%x,D%x,E%x,F%x,G%x,H%x,I%x,J%x,K%x>", DataB->GetEventoInCorso().idEvento,
DataB->GetEventoInCorso().numEvento, DataB->GetEventoInCorso().subEvento,
DataB->GetNextEvento().idEvento, DataB->GetNextEvento().numEvento, DataB->GetNextEvento().subEvento,
gara.tkTempo, gara.tkDurata - gara.tkTempo,
gara.laps, gara.gDurata > 0 ? (gara.gDurata - gara.laps):0, gara.flInCorso ? (gara.gDurata > 0 ? 2:1):0,
gara.flFineGara);
ps->Add(s);
s= "<END_DATI_GARA>";
ps->Add(s);
Send(ps);
}
catch(...){}
}
void __fastcall TDataNet::Timer1Timer(TObject *Sender)
{
Timer1->Enabled= false;
SetDatiGara();
Timer1->Enabled= true;
}
void __fastcall TDataNet::IdTCPServer1Connect(TIdContext *AContext)
{
TDatiClient* dati;
dati= new TDatiClient;
dati->pThread= AContext;
AContext->Connection->IOHandler->ReadTimeout= 200;
AContext->Data= (TObject*)dati;
try
{
TList* lista;
lista= listaClient->LockList();
lista->Add(dati);
connessioni= lista->Count;
if(FmainWnd)
PostMessage(FmainWnd, WM_EVENTO_TCP, ID_CONNESSO, lista->Count);
int idEvento= DataB->GetEventoInCorso().idEvento;
if(idEvento)
SetCambioStato(idEvento, STATO_EVENTO_START, AContext);
}
__finally
{
listaClient->UnlockList();
}
}
void __fastcall TDataNet::IdTCPServer1Disconnect(TIdContext *AContext)
{
TDatiClient* dati;
dati= (TDatiClient*)AContext->Data;
AContext->Data= NULL;
try
{
listaClient->Remove(dati);
TList* lista;
lista= listaClient->LockList();
connessioni= lista->Count;
if(FmainWnd)
PostMessage(FmainWnd, WM_EVENTO_TCP, ID_DISCONNESSO, lista->Count);
}
__finally
{
listaClient->UnlockList();
}
delete dati;
}
void __fastcall TDataNet::IdTCPServer1Execute(TIdContext *AContext)
{
Sleep(100);
try
{
AContext->Connection->IOHandler->ReadStrings(psRx, -1);
if(psRx->Count >= 2 && psRx->Strings[0] == "<LAST_MINUTE>" && psRx->Strings[psRx->Count-1] == "<END_LAST_MINUTE>")
{
psRx->Delete(0);
psRx->Delete(psRx->Count-1);
if(FmainWnd)
SendMessage(FmainWnd, WM_EVENTO_TCP, ID_LAST_MINUTE, (unsigned int)psRx);
}
psRx->Clear();
}
catch(...) {}
AContext->Connection->CheckForGracefulDisconnect();
}
デバッグを実行します。どのコード行で例外が発生しているかを調べる。スタックオーバーフローはデバッガではありません。 –
エラーメッセージは、NULLポインターから-48バイトオフセットしたものにアクセスしていることを意味します。私はこのコードであらゆる種類の問題を見る。これは、TIdTCPServerとのサーバーツークライアント通信の実装を推奨するものではありません。より安全であるためには書き直す必要があります。私は明日の答えを投稿します。 –
レミーありがとう、あなたのコードを調べてください – Mirco