向大侠们求助:
本人现在用delphi开发一个通信服务器程序,在比较固定的十几个Socket连接之间转发数据包,
现在问题就是有当客户端连接断开时服务器程序有时死掉,无任何提示就退出(并不每次断开都出现)
请问大家有什么解决办法
本人是用ServerSocket控件守侯连接TTcpForm.ServerSocket1Accept(Sender: TObject; Socket: TCustomWinSocket);
begin
ShowMess('有来自[' + Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort) + ']的连接!');
//...
lenact := Socket.ReceiveBuf(Buf[i], 1024);
//校验初始化数据包(校验连接的合法性)
//...
//建立连接线程
case Buf[5] of
2: ConnectThread := TCollectThread.Create(True); //前置机连接
3: ConnectThread := TMoniterThread.Create(True); //监控平台连接
end;
ConnectThread.Socket := Socket;
//线程添加到管理对象
ConnectMannage.AddConnect(ConnectThread);
//线程启动
ConnectThread.Resume;
end;//TMoniterThread连接线程实现
constructor TMoniterThread.Create(Flag: Boolean);
begin
inherited Create(Flag);
CloseFlag := False; //退出标记
FConnectType := 4; //连接类型
SockeErroFlag := False; //Socket连接出错标记
end;procedure TMoniterThread.Execute;
begin
while not CloseFlag do
begin
Sleep(50);
//当Socke出错时并不马上退出线程,让线程管理对象置退出标记再退出线程
if SockeErroFlag then
begin
SendMessage(MainForm.Handle, WM_ConnectSocketErro, FIndexNo, 0);
Continue;
end;
//读Socket数据
SockeErroFlag := False;
FillChar(Buf, Length(Buf), 0);
i := 0;
repeat
begin
try
lenact := Socket.ReceiveBuf(Buf[i], 1024);
except
SockeErroFlag := True;
end;
if SockeErroFlag then
Break;
if lenact = 0 then //为0表示Socket错误
begin
SockeErroFlag := True;
Break;
end;
if lenact = -1 then //没有数据
Break;
i := i + lenact;
if i > 1024 then
Break;
end
until lenact <= 0;
lenact := i;
if SockeErroFlag then
Continue;
//分解处理数据包
//...
//------------------读队列发放数据包------------------------
while FQuery.PackCount > 0 do
begin
pPack := FQuery.GetPackage;
try
lenact := Socket.SendBuf(pPack.Buf[0], pPack.PackLen);
except
SockeErroFlag := True;
end;
if SockeErroFlag then
Break;
if lenact = -1 then
begin
SockeErroFlag := True;
Break;
end;
end;
end;
PostMessage(MainForm.Handle, WM_ConnectQuit, FIndexNo, 0);
end;//处理消息WM_ConnectSocketErro
procedure TMainForm.ThreadConnetSocketError(var message: Tmessage);
var
cIndexNo: Integer;
begin
cIndexNo := message.WParam; //连接索引号
ConnectMannage.DelConnect(cIndexNo); //连接管理对象删除连接
end;//处理消息WM_ConnectQuit
procedure TMainForm.ThreadConnetQuit(var message: Tmessage);
var
cIndexNo: Integer;
begin
cIndexNo := message.WParam; //连接索引号
ConnectMannage.DelConnect(cIndexNo); //删除连接
end;
//连接管理对象删除指定连接
function TConnectMannage.DelConnect(cIndexNo: Integer): Boolean;
var
CnetObject: TConnectThread;
i: Integer;
begin
EnterCriticalSection(CS_M);
Result := False;
for i := FConnectList.Count - 1 downto 0 do
begin
CnetObject := FConnectList[i];
if CnetObject.IndexNo = cIndexNo then
begin
CnetObject.FreeOnTerminate := True;
CnetObject.CloseFlag := True;
CnetObject.Terminate;
FConnectList.Delete(i);
Result := True;
end;
end;
LeaveCriticalSection(CS_M);
end;
本人现在用delphi开发一个通信服务器程序,在比较固定的十几个Socket连接之间转发数据包,
现在问题就是有当客户端连接断开时服务器程序有时死掉,无任何提示就退出(并不每次断开都出现)
请问大家有什么解决办法
本人是用ServerSocket控件守侯连接TTcpForm.ServerSocket1Accept(Sender: TObject; Socket: TCustomWinSocket);
begin
ShowMess('有来自[' + Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort) + ']的连接!');
//...
lenact := Socket.ReceiveBuf(Buf[i], 1024);
//校验初始化数据包(校验连接的合法性)
//...
//建立连接线程
case Buf[5] of
2: ConnectThread := TCollectThread.Create(True); //前置机连接
3: ConnectThread := TMoniterThread.Create(True); //监控平台连接
end;
ConnectThread.Socket := Socket;
//线程添加到管理对象
ConnectMannage.AddConnect(ConnectThread);
//线程启动
ConnectThread.Resume;
end;//TMoniterThread连接线程实现
constructor TMoniterThread.Create(Flag: Boolean);
begin
inherited Create(Flag);
CloseFlag := False; //退出标记
FConnectType := 4; //连接类型
SockeErroFlag := False; //Socket连接出错标记
end;procedure TMoniterThread.Execute;
begin
while not CloseFlag do
begin
Sleep(50);
//当Socke出错时并不马上退出线程,让线程管理对象置退出标记再退出线程
if SockeErroFlag then
begin
SendMessage(MainForm.Handle, WM_ConnectSocketErro, FIndexNo, 0);
Continue;
end;
//读Socket数据
SockeErroFlag := False;
FillChar(Buf, Length(Buf), 0);
i := 0;
repeat
begin
try
lenact := Socket.ReceiveBuf(Buf[i], 1024);
except
SockeErroFlag := True;
end;
if SockeErroFlag then
Break;
if lenact = 0 then //为0表示Socket错误
begin
SockeErroFlag := True;
Break;
end;
if lenact = -1 then //没有数据
Break;
i := i + lenact;
if i > 1024 then
Break;
end
until lenact <= 0;
lenact := i;
if SockeErroFlag then
Continue;
//分解处理数据包
//...
//------------------读队列发放数据包------------------------
while FQuery.PackCount > 0 do
begin
pPack := FQuery.GetPackage;
try
lenact := Socket.SendBuf(pPack.Buf[0], pPack.PackLen);
except
SockeErroFlag := True;
end;
if SockeErroFlag then
Break;
if lenact = -1 then
begin
SockeErroFlag := True;
Break;
end;
end;
end;
PostMessage(MainForm.Handle, WM_ConnectQuit, FIndexNo, 0);
end;//处理消息WM_ConnectSocketErro
procedure TMainForm.ThreadConnetSocketError(var message: Tmessage);
var
cIndexNo: Integer;
begin
cIndexNo := message.WParam; //连接索引号
ConnectMannage.DelConnect(cIndexNo); //连接管理对象删除连接
end;//处理消息WM_ConnectQuit
procedure TMainForm.ThreadConnetQuit(var message: Tmessage);
var
cIndexNo: Integer;
begin
cIndexNo := message.WParam; //连接索引号
ConnectMannage.DelConnect(cIndexNo); //删除连接
end;
//连接管理对象删除指定连接
function TConnectMannage.DelConnect(cIndexNo: Integer): Boolean;
var
CnetObject: TConnectThread;
i: Integer;
begin
EnterCriticalSection(CS_M);
Result := False;
for i := FConnectList.Count - 1 downto 0 do
begin
CnetObject := FConnectList[i];
if CnetObject.IndexNo = cIndexNo then
begin
CnetObject.FreeOnTerminate := True;
CnetObject.CloseFlag := True;
CnetObject.Terminate;
FConnectList.Delete(i);
Result := True;
end;
end;
LeaveCriticalSection(CS_M);
end;
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货