delphi 中的 serversocket 问题,急等,在线寻求帮助 用的是 serversocket控件做的一个 “心跳监控”软件 ,用的是长连接模式“stNonBlocking”,
程序一打开,还能监听540多个客户端,属于正常情况,但是在运行20分钟后,就发现 在线的客户端只有
200个左右,有时候甚至只有几十个,把监听服务停掉,然后在启动监听服务又能监听到 500 多个,过20多
分钟过后,又是只能监听到一部分,请问,这个事怎么回事呢?在线等待,急用呀。。
程序一打开,还能监听540多个客户端,属于正常情况,但是在运行20分钟后,就发现 在线的客户端只有
200个左右,有时候甚至只有几十个,把监听服务停掉,然后在启动监听服务又能监听到 500 多个,过20多
分钟过后,又是只能监听到一部分,请问,这个事怎么回事呢?在线等待,急用呀。。
function TForm_ShiPing.Start_ser():String;
begin //验证端口号是否正确
try
StrToInt(EditProt.Text);
except
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:', Now)+'【端口填写错误,请重新填写】');
EditProt.SetFocus;
Exit;
end; //启动服务
try ServerSocket_ser.Port := StrToInt(EditProt.Text);
ServerSocket_ser.Active := true;
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:',Now)+'【启动成功】'); Label_djs.Caption := Edit_time.Text;
But_start.Enabled := false;
EditProt.Enabled := false;
Edit_time.Enabled := false;
But_stop.Enabled := true;
//启动计时器
Timer_cl.Enabled := true;
//初始化计数器数据
timeNum := StrToInt(Edit_time.Text);
//初始化接收到的心跳数据
reNum := 0;
//初始化已处理的心跳数据
proNum := 0; //创建TstringList
strDataCl := TStringList.Create;
//写入日志文件
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+'【启动成功】','0'); except
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:',Now)+'【启动失败】'); //写入日志文件
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+'【启动失败】','0'); Exit;
end;
end;ServerSocket 控件这是如下:
Action -> false
Port -> 8375
ServerType -> stNonBlocking
Service ->
Tag -> 0
ThreadCacheSize -> 10
下面的服务器都是在1分钟发一个心跳包上来,然后我就把收到的心跳包解析后更新到数据库,
现在就出现了运行一会儿 就接收不到大部分心跳,其中说明一点的是,500多个服务器心跳全部正常
请问这个事什么问题呢?
希望高手帮忙看看,在线等待。。急用
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, ExtCtrls, ADODB, DB, ComCtrls,
IdBaseComponent, IdComponent, IdTCPServer, IdTCPConnection,
IdSimpleServer;type
TForm_ShiPing = class(TForm)
Label1: TLabel;
EditProt: TEdit;
MemoMsg: TMemo;
ServerSocket_ser: TServerSocket;
Timer_cl: TTimer;
GroupBox1: TGroupBox;
Label_djs: TLabel;
ADOConnection_sql: TADOConnection;
GroupBox2: TGroupBox;
Label_Cl: TLabel;
StatusBar_state: TStatusBar;
Label_dd: TLabel;
Label_clz: TLabel;
Label3: TLabel;
ADOStoredProc_sql: TADOStoredProc;
Edit_time: TEdit;
Label2: TLabel;
But_start: TButton;
But_stop: TButton;
Timer_server: TTimer;
IdTCPServer_server: TIdTCPServer;
procedure FormCreate(Sender: TObject);
procedure But_stopClick(Sender: TObject);
procedure ServerSocket_serClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket_serClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket_serClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure Timer_clTimer(Sender: TObject);
procedure But_startClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ServerSocket_serClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure Timer_serverTimer(Sender: TObject);
procedure IdTCPServer_serverExecute(AThread: TIdPeerThread);
procedure IdTCPServer_serverConnect(AThread: TIdPeerThread);
procedure IdTCPServer_serverDisconnect(AThread: TIdPeerThread);
private
{ Private declarations }
function Data_Cl():string;
function Start_ser():String;
function Indy_Start_ser():String;
function IntToBinaryStr(TheVal: LongInt): string;
public
{ Public declarations }
end;var
Form_ShiPing: TForm_ShiPing;
//记录一定时间内取得的sn
strDataCl : TStringList;
//倒计时记录器
timeNum : Integer;
//接收到的心跳数据
reNum : Integer;
//已处理的心跳数据
proNum : Integer;
implementationuses DateUtils,ProgLog;{$R *.dfm}
procedure TForm_ShiPing.FormCreate(Sender: TObject);
begin
//清空文本
MemoMsg.Clear;
//启动服务器
Start_ser();
// Indy_Start_ser();
end;procedure TForm_ShiPing.But_stopClick(Sender: TObject);
begin
//停止服务器
ServerSocket_ser.Active := false;
MemoMsg.Lines.Add(FormatDateTime('HH时:',Now)+'【服务器停止成功】');
But_start.Enabled := true;
But_stop.Enabled := false;
EditProt.Enabled := true;
Edit_time.Enabled := true;
//关闭计时器
Timer_cl.Enabled := false;
//写入日志文件
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+'【服务器停止成功】','0');
end;procedure TForm_ShiPing.ServerSocket_serClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
try
//客户端连接后,实时统计客户端个数
// Form_ShiPing.Caption := '视频心跳监控----'+IntToStr(ServerSocket_ser.Socket.ActiveConnections)
// +'个客户端';
except
// MemoMsg.Lines.Add('conn:err');
end;
end;procedure TForm_ShiPing.ServerSocket_serClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
//断开连接统计客户端
//Form_ShiPing.Caption := '视频心跳监控----'+IntToStr(ServerSocket_ser.Socket.ActiveConnections-1)
// +'个客户端';
end;
Socket: TCustomWinSocket);var
//计数器
num : Integer;
//循环变量
i : Integer;
//存储接收到的数据
dataBuf : array[0..48] of Byte;
//存储转换后的sn
strData : String;
//存储转换后的状态
strState : String;
//临时变量
strTemps : string;
strTempYzState : Integer;
StrTep : String;
begin try Socket.ReceiveBuf(dataBuf,49);
strTemps := chr(dataBuf[0])+'';
num := Integer(dataBuf[4]);
except
end;
if strTemps = '#' then
begin
//读取客户端跳上来的数据
for i:=5 to num+4 do
begin
try if i <= num then
begin
strData := strData+chr(dataBuf[i]);
end
else
begin
strTempYzState := strTempYzState+Integer(dataBuf[i]);
end
except
end;
end; StrTep := IntToBinaryStr(strTempYzState);
if Length(StrTep) = 1 then
begin
StrTep := '000'+ StrTep;
end
else if Length(StrTep) = 2 then
begin
StrTep := '00'+ StrTep;
end
else if Length(StrTep) = 3 then
begin
StrTep := '0'+ StrTep;
end;
strState := StrTep;
//取得的sn写入TstringList
strDataCl.Add(strData+':'+strState+';');
//实时记录最新接收数据个数
// reNum := reNum+1; //检测窗体当达到500条时执行清空
if MemoMsg.Lines.Count > 500 then
begin
MemoMsg.Clear;
end; //再窗体中显示数据
MemoMsg.Lines.Add(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort)+ '【SN】'+strData+'【状态】'+strState); //写入日志文件
//programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort)+ '个数:'+IntToStr(num)+' 【SN】'+strData+'【状态】'+strState,'0'); //状态栏显示数据
//StatusBar_state.Panels[0].Text :='状态: 已收到数据:'+IntToStr(reNum)+' 条 已处理数据:'+IntToStr(proNum)+' 条 ';
end
else
begin
//不正常接入写入日志文件
programLog(FormatDateTime('【YY-MM-DD HH:NN:SS】 ', Now)+' 不正常数据接入:'+Socket.RemoteAddress,'0'); end;
end;procedure TForm_ShiPing.Timer_clTimer(Sender: TObject);
var
//临时测试变量
st :string;
begin
if timeNum = 0 then
begin
Timer_cl.Enabled := false;
Label_clz.Color := clLime; //调用处理数据方法
st := Data_Cl(); //处理完成,更改状态
if st = '0' then
begin
Label_dd.Color := clLime;
Label_clz.Color := clred;
end; Timer_cl.Enabled := true;
timeNum := StrToInt(Edit_time.Text); end
else
begin
timeNum := timeNum-1;
end;
if timeNum < 10 then
begin
Label_djs.Caption := '0'+IntToStr(timeNum);
end
else
begin
Label_djs.Caption := IntToStr(timeNum);
end;end;
//数据处理函数
function TForm_ShiPing.Data_Cl():String;
var
strData_Ls : TStringList;
//循环变量
i : Integer;
//循环变量
k : Integer;
//统计数组个数
strNum : Integer;
//临时变量
strTemp :String;
begin
strData_Ls := TStringList.Create;
strNum := strDataCl.Count; //判断list里面是否有数据,有则执行
if strNum <> 0 then
begin
for i:=0 To strNum-1 do
begin
strData_Ls.Add(strDataCl[i]);
end; //清空记录数据
strDataCl.Clear;
//写入日志文件
programLog('*******************************','1');
for k:=0 To strData_Ls.Count-1 do
begin
strTemp := strTemp+strData_Ls[k];
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+strData_Ls[k],'1');
end; try ADOStoredProc_sql.Parameters.ParamByName('thingsStr').Value := strTemp;
ADOStoredProc_sql.ExecProc; programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+' 执行存储过程成功','1');
programLog('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@','1'); //统计成功更新数据个数
// proNum := proNum+strData_Ls.Count;
//状态栏显示数据
//StatusBar_state.Panels[0].Text :='状态: 已收到数据:'+IntToStr(reNum)+' 条 已处理数据:'+IntToStr(proNum)+' 条 '; except
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+'执行存储过程失败','1');
programLog('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@','1');
end;
ADOStoredProc_sql.Active := false; end;
Result := '0';
end;//启动服务器方法
function TForm_ShiPing.Start_ser():String;
begin //验证端口号是否正确
try
StrToInt(EditProt.Text);
except
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:', Now)+'【端口填写错误,请重新填写】');
EditProt.SetFocus;
Exit;
end; //启动服务
try ServerSocket_ser.Port := StrToInt(EditProt.Text);
ServerSocket_ser.Active := true;
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:',Now)+'【启动成功】'); Label_djs.Caption := Edit_time.Text;
But_start.Enabled := false;
EditProt.Enabled := false;
Edit_time.Enabled := false;
But_stop.Enabled := true;
//启动计时器
Timer_cl.Enabled := true;
//初始化计数器数据
timeNum := StrToInt(Edit_time.Text);
//初始化接收到的心跳数据
reNum := 0;
//初始化已处理的心跳数据
proNum := 0; //创建TstringList
strDataCl := TStringList.Create;
//写入日志文件
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+'【启动成功】','0'); except
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:',Now)+'【启动失败】'); //写入日志文件
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+'【启动失败】','0'); Exit;
end;
end;
//IndyServer服务启动
function TForm_ShiPing.Indy_Start_ser():String;
begin
try IdTCPServer_server.DefaultPort := StrToInt(EditProt.Text);
IdTCPServer_server.Active := true;
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:',Now)+'【启动成功】');
except
ShowMessage('启动错误');
Exit;
end;end;
procedure TForm_ShiPing.But_startClick(Sender: TObject);
begin
//启动服务器
Start_ser();
end;procedure TForm_ShiPing.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
//停止服务器
ServerSocket_ser.Active := false;
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:',Now)+'【服务器停止成功】');
But_start.Enabled := true;
But_stop.Enabled := false;
EditProt.Enabled := true;
Edit_time.Enabled := true;
//关闭计时器
Timer_cl.Enabled := false;
//写入日志文件
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+'【服务器停止成功】','0');
end;
//int型转换成二进制
function TForm_ShiPing.IntToBinaryStr(TheVal: LongInt): string;
var
counter: LongInt;
begin
if TheVal = 0 then begin
result := '0';
exit;
end;
result := '';
counter := $80000000;
while ((counter and TheVal) = 0) do begin
counter := counter shr 1;
if (counter = 0) then break;
end;
while counter > 0 do begin
if (counter and TheVal) = 0 then result := result + '0'
else result := result + '1';
counter := counter shr 1;
end;
end;
procedure TForm_ShiPing.ServerSocket_serClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode := 0;
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+'【10053 错误】','0');
end;
begin //停止服务器
ServerSocket_ser.Active := false;
MemoMsg.Lines.Add(FormatDateTime('HH时:',Now)+'【服务器停止成功】');
But_start.Enabled := true;
But_stop.Enabled := false;
EditProt.Enabled := true;
Edit_time.Enabled := true;
//关闭计时器
Timer_cl.Enabled := false;
//写入日志文件
programLog(FormatDateTime('[YY-MM-DD HH:NN:SS] ', Now)+'【服务器停止成功】','0'); //清空状态框
MemoMsg.Clear; //启动服务器
Start_ser();
end;procedure TForm_ShiPing.IdTCPServer_serverExecute(AThread: TIdPeerThread);
begin
// MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:',Now)+'收到数据');
end;procedure TForm_ShiPing.IdTCPServer_serverConnect(AThread: TIdPeerThread);
begin
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:',Now)+'有连接');
end;procedure TForm_ShiPing.IdTCPServer_serverDisconnect(
AThread: TIdPeerThread);
begin
MemoMsg.Lines.Add(FormatDateTime('HH时NN分SS秒:',Now)+'断开连接');
end;end.
64,300,1000,2000??
[email protected] 唐姊