现在的位置: 首页 > 综合 > 正文

数据库连接不成功时的解决办法。

2012年12月21日 ⁄ 综合 ⁄ 共 3284字 ⁄ 字号 评论关闭

连接远程数据库服务器,如果远程服务器未开机,程序就会停顿几分钟,就象死了
一样(BDE一般约3分钟后恢复正常)。

在连接远程数据库服务器前,先使用TClientSocket连接端口(测试端口,时间3秒足够),如果TClientSocket连接不上,就不再使用数据库连接组件(ADO-TADOConnection或BDE-TDatabase)连接了。

使用TClientSocket连接端口时,要使用线程来控制时间,并使用阻塞型连接,线程内时间一到就取消Socket, (如果端口有效,那是一连就通,如数据库服务未开,而服务器存在,也很快被拒绝,而服务器不存在时,可能时间较长,这时TClientSocket将发生作用)。

//---------------------------------------------------------------------------
//     线程写法:
//---------------------------------------------------------------------------
class TThreadConnPort : public TThread
{
private:
    int MaxTimeOut;
    TClientSocket *SocketPoint;
    void __fastcall Execute(void);
public:
    __fastcall TThreadConnPort(TClientSocket *ClientSocket, int TimeOut);
};
//---------------------------------------------------------------------------
__fastcall TThreadConnPort::TThreadConnPort(TClientSocket *ClientSocket,
                int TimeOut) : TThread(true)
{
    SocketPoint = ClientSocket;
    MaxTimeOut = TimeOut;    //  控制时间
    FreeOnTerminate = true;
    Resume();
}
//---------------------------------------------------------------------------
void __fastcall TThreadConnPort::Execute(void)
{
    int TimeCount = 0;
    Sleep(300);
    while (!Terminated)
    {
        TimeCount++;
        try
        {
            if (SocketPoint->Tag) break;
            else if (TimeCount > MaxTimeOut * 10)
            {
                SocketPoint->Socket->Close();
                SocketPoint->Close();
                break;
            }
        }
        catch (...)
        {
            break;
        }
        Sleep(100);
    }
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
//    ConnectionServerPort() 是测试主机与端口的函数
// AnsiString ServerIp 主机名或IP地址,
// int ServerPort   端口号,1-65535
// int TimeOut    控制时间,秒
// 这个函数返回值表示远程主机的数据库服务端口是否有效
//---------------------------------------------------------------------------
bool __fastcall TMainForm::ConnectionServerPort(AnsiString ServerIp,
                             int ServerPort, int TimeOut)
{
    bool PortConnected;
    TClientSocket *ClientSocket = new TClientSocket(this);
    ClientSocket->Tag = 0;
    ClientSocket->OnConnect = ClientSocketConnect;  //  连接成功时,将Tag置1表示成功
    ClientSocket->OnError = ClientSocketError; //  连接异常时处理函数
    ClientSocket->Host = ServerIp;
    ClientSocket->Port = ServerPort;
    ClientSocket->ClientType = ctBlocking;
    TThreadConnPort * CheckSocket = new TThreadConnPort(ClientSocket, TimeOut);
    try
    {
        ClientSocket->Open();
        CheckSocket->Terminate();
    }
    catch (...)
    {
        ClientSocket->Tag=0;
    }
    PortConnected = ClientSocket->Tag == 1;  //  查询是否成功
    delete ClientSocket;
    return PortConnected;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ClientSocketConnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
    TClientSocket *SocketId = (TClientSocket *)Sender;
    SocketId->Tag = 1;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ClientSocketError(TObject *Sender,
      TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
    TClientSocket *SocketId = (TClientSocket *)Sender;
    if (ErrorEvent == eeLookup) SocketId->Tag = 2;
    else SocketId->Tag = 3;
    ErrorCode = 0;
}
//---------------------------------------------------------------------------

//  在连接数据库前使用 ConnectionServerPort() 函数测试端口
// 由于连接时,可能使用客户端工具生成的连接名,那么,要进行地址解释。

抱歉!评论已关闭.