H
hardblue
Unregistered / Unconfirmed
GUEST, unregistred user!
type
TForm1 = class(TForm)
console: TMemo;
................省略
var
Form1: TForm1;
cscx:tcriticalsection; //费用查询用 线程同步对象
cssf:tcriticalsection; //用户收费用 线程同步对象
cszx:tcriticalsection; //交易注销用 线程同步对象
cscd:tcriticalsection; //重打发票用 线程同步对象
dz_data:string; //对帐数据字符串 注::每次对帐结束后,必须将其置为空串
is_first:boolean; //对帐的时候是否是第一包数据
implementation
{$R *.dfm}
//----客户端连接事件----------------------------------------------------------//
procedure TForm1.serverConnect(AThread: TIdPeerThread);
begin
console.Lines.Add(datetimetostr(now()) + ' '+ '客户端连接成功! IP地址:'+ athread.Connection.Socket.Binding.PeerIP + ' 线程ID:' + inttostr(athread.ThreadID) );
end;
//----------------------------------------------------------------------------//
//-------接收数据事件,客户端向服务器传送数据时触发----------------------------//
procedure TForm1.serverExecute(AThread: TIdPeerThread);
var
r_data:string; //接收的字符串
sl:tstringlist; //分隔接收数据为各个字段
lenstr:string; //pklen:数据长度字段
package_len:integer; //数据包长度 = 去掉pklen字段以后的长度
dz_rq:string; //对帐日期
xym:string; //响应码
begin
with athread.Connection do
begin
//athread.Connection.ReadTimeout := 5000; //设置读数据超时时间为5秒
sl:=tstringlist.Create; //创建tstringlist
lenstr:= readstring(4); //读取数据长度
try
package_len := strtoint(lenstr);
except
begin
console.Lines.Add('接收数据长度错误!');
exit ;
end;
end;
//try
//begin
r_data := readstring(package_len); //读取数据包
console.Lines.Add(' 收到的数据:'+ r_data) ;
sl:= split(r_data,'|'); //将各个字段分解出来
//-----------------判断是何种操作-------------------------------------//
if sl.Strings[1] = '1111' then //查询操作
begin
cscx.Enter; //进入临界区,进行保护
query(sl.Strings[2],athread);
r_data := '';
cscx.Leave; //操作完成,离开临界区
end;
if sl.Strings[1]='2222' then //收费功能
begin
cssf.Enter; //进行线程保护区
sf ( sl.Strings[3] , sl.strings[2] , sl.Strings[4] ,
sl.strings[5] , sl.Strings[6] , athread );
r_data:='';
cssf.Leave; //离开线程保护区
end;
end;
end;
procedure tform1.query(yhbh:String;athread:tidpeerthread);
var
变量定义,省略。。。。。。。
begin
//----向MEMO输出信息---------------------------------------------------//
console.Lines.Add(datetimetostr(now()) + ' ' + '客户端查询请求! IP地址: '
+ athread.Connection.Socket.Binding.PeerIP + ' 查询用户编号:' + yhbh);
//----进行查询------------------------------------------------------------//
qqls('1111',yhbh,''); //自定义函数
try
begin
query_cx.Close;
query_cx.Parameters.ParamByName('yhbh').Value := trim(yhbh);
if query_cx.Prepared=false then query_cx.Prepared;
query_cx.Open;
end;
except
begin
send('','0','1111','100',athread);
console.Lines.Add('查询时出错');
exit;
end;
end;
if query_cx.RecordCount=0 then //------------------------------如果记录为0//
begin
send('','0','1111','100',athread);
exit;
end
else//----------------------------------------------------------如果有数据//
begin
while not query_cx.Eof do
begin
......从数据库取值,代码省略
query_cx.Next;
end;
//--查询结束----------------------------------------------------------------//
if bz = false then
begin
send('','0','1111','101',athread); //自定义函数
bz:=true;
end
else
begin
if zje<0 then //总金额小于零
begin
send('','0','1111','101',athread);
end
else if zje = 0 then
begin
send('','0','1111','100',athread);
end
else
begin
cnt := query_cx.RecordCount;
if sfbz='0' then
begin
send_cmd := yhbh + '|' + yhxm + '|' + yhdz + '|' + floattostr(sfmj)
+ '|' + floattostr(zje)+ '|' +inttostr(cnt)+ '|4'+ fyxx;
send(send_cmd,'0','1111','000',athread); //发送数据,自定义函数
end
else
begin
send('','0','1111','101',athread);
end;
end;
end;
end;
//end if--------------------------------------------------------------------//
athread.Connection.InputBuffer.Clear; //清接收缓冲区
exit;
end;
procedure tform1.sf(yhbh:String;lsh:string;skje:string;jysj_date:string;jysj_time:string;athread:tidpeerthread);
var
变量定义,省略。。。。。。。
begin
qqls('2222',yhbh,lsh);
//----向console输出信息---------------------------------------------------//
console.Lines.Add(datetimetostr(now()) + ' ' + '客户端收费请求! IP地址: '
+ athread.Connection.Socket.Binding.PeerIP + ' 收费用户编号:' + yhbh);
//----进行查询------------------------------------------------------------//
query_sf.Close;
query_sf.Parameters.ParamByName('yhbh').Value := trim(yhbh);
if query_sf.Prepared=false then query_sf.Prepared;
query_sf.Open;
if query_sf.RecordCount=0 then //如果记录为0-------------------//
begin
send('','0','2222','100',athread);
end
else//如果有数据
begin
while not query_sf.Eof do
begin
.....从数据库取值,代码省略
query_sf.Next;
end;
//--查询结束----------------------------------------------------------------//
.........
sfls.CommandText:=inssql;
try
begin
sfls.Execute;
send(send_cmd,'0','2222','000',athread); //发送数据
end;
except //如果操作数据库异常,则向银行发送收费交易错误代码200
begin
send(send_cmd,'0','2222','200',athread);
end;
end;
end;
end;
end;
//----记流水帐函数------------------------------------------------------------//
function TForm1.qqls(jydm, yhbh: string;lsh:string): boolean;
var
sql:string;
begin
ins_ls.Parameters.ParamByName('jydm').Value:= jydm;
ins_ls.Parameters.ParamByName('jysj').Value:=now();
ins_ls.Parameters.ParamByName('yhbh').Value:= yhbh;
sql:= ins_ls.CommandText;
ins_ls.Execute;
end;
//----发送数据函数,加入消息头并发发送数据-------------------------------------//
procedure TForm1.send(cmd: string; flag:string;code:string;reply:string;athread: tidpeerthread);
var
send_cmd:string;
temp_cmd:string;
begin
if athread.Connection.Connected then
begin
if length(trim(cmd))>0 then
begin
cmd:= '|' + flag + '|' + code + '|' + reply + '|' + cmd +'|';
send_cmd := formatfloat('00##',length(cmd)) + cmd //组织要传送的数据
end
else
begin
cmd:= '|' + flag + '|' + code + '|' + reply + '|';
send_cmd := formatfloat('00##',length(cmd)) + cmd ; //组织要传送的数据
end;
athread.Connection.Write(send_cmd); //发送数据
console.Lines.Add(datetimetostr(now()) + ' ' + '响应客户端请求! IP地址: '
+ athread.Connection.Socket.Binding.PeerIP );
console.Lines.add(' 服务器发送数据包: ' + send_cmd);
end
else
begin
console.Lines.Add('连接已经断开!无法发送数据...');
exit;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
console.Lines.Clear;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
server.DefaultPort:=9999;
server.Active:=true;
console.Lines.Add(datetimetostr(now()) + ' 正在监听端口6666......');
console.SetFocus;
end;
procedure TForm1.serverException(AThread: TIdPeerThread;
AException: Exception);
begin
console.Lines.Add('System Exception message: ' + aexception.Message);
end;
procedure TForm1.serverDisconnect(AThread: TIdPeerThread);
begin
console.Lines.Add('disconnected.....');
end;
initialization
// 初始化线程同步对象
cscx:=tcriticalsection.Create;
cssf:=tcriticalsection.Create;
cszx:=tcriticalsection.Create;
cscd:=tcriticalsection.Create;
is_first:=true;
end.
运行一段时间后,会出错误,具体表现是当客户端再发请求过来的时候,服务端能看到(MEMO上的输出信息),但是不能响应客户端了,就是不会发送数据了。。
水平有限,实在找不出原因了,麻烦大家帮忙看看什么问题。
TForm1 = class(TForm)
console: TMemo;
................省略
var
Form1: TForm1;
cscx:tcriticalsection; //费用查询用 线程同步对象
cssf:tcriticalsection; //用户收费用 线程同步对象
cszx:tcriticalsection; //交易注销用 线程同步对象
cscd:tcriticalsection; //重打发票用 线程同步对象
dz_data:string; //对帐数据字符串 注::每次对帐结束后,必须将其置为空串
is_first:boolean; //对帐的时候是否是第一包数据
implementation
{$R *.dfm}
//----客户端连接事件----------------------------------------------------------//
procedure TForm1.serverConnect(AThread: TIdPeerThread);
begin
console.Lines.Add(datetimetostr(now()) + ' '+ '客户端连接成功! IP地址:'+ athread.Connection.Socket.Binding.PeerIP + ' 线程ID:' + inttostr(athread.ThreadID) );
end;
//----------------------------------------------------------------------------//
//-------接收数据事件,客户端向服务器传送数据时触发----------------------------//
procedure TForm1.serverExecute(AThread: TIdPeerThread);
var
r_data:string; //接收的字符串
sl:tstringlist; //分隔接收数据为各个字段
lenstr:string; //pklen:数据长度字段
package_len:integer; //数据包长度 = 去掉pklen字段以后的长度
dz_rq:string; //对帐日期
xym:string; //响应码
begin
with athread.Connection do
begin
//athread.Connection.ReadTimeout := 5000; //设置读数据超时时间为5秒
sl:=tstringlist.Create; //创建tstringlist
lenstr:= readstring(4); //读取数据长度
try
package_len := strtoint(lenstr);
except
begin
console.Lines.Add('接收数据长度错误!');
exit ;
end;
end;
//try
//begin
r_data := readstring(package_len); //读取数据包
console.Lines.Add(' 收到的数据:'+ r_data) ;
sl:= split(r_data,'|'); //将各个字段分解出来
//-----------------判断是何种操作-------------------------------------//
if sl.Strings[1] = '1111' then //查询操作
begin
cscx.Enter; //进入临界区,进行保护
query(sl.Strings[2],athread);
r_data := '';
cscx.Leave; //操作完成,离开临界区
end;
if sl.Strings[1]='2222' then //收费功能
begin
cssf.Enter; //进行线程保护区
sf ( sl.Strings[3] , sl.strings[2] , sl.Strings[4] ,
sl.strings[5] , sl.Strings[6] , athread );
r_data:='';
cssf.Leave; //离开线程保护区
end;
end;
end;
procedure tform1.query(yhbh:String;athread:tidpeerthread);
var
变量定义,省略。。。。。。。
begin
//----向MEMO输出信息---------------------------------------------------//
console.Lines.Add(datetimetostr(now()) + ' ' + '客户端查询请求! IP地址: '
+ athread.Connection.Socket.Binding.PeerIP + ' 查询用户编号:' + yhbh);
//----进行查询------------------------------------------------------------//
qqls('1111',yhbh,''); //自定义函数
try
begin
query_cx.Close;
query_cx.Parameters.ParamByName('yhbh').Value := trim(yhbh);
if query_cx.Prepared=false then query_cx.Prepared;
query_cx.Open;
end;
except
begin
send('','0','1111','100',athread);
console.Lines.Add('查询时出错');
exit;
end;
end;
if query_cx.RecordCount=0 then //------------------------------如果记录为0//
begin
send('','0','1111','100',athread);
exit;
end
else//----------------------------------------------------------如果有数据//
begin
while not query_cx.Eof do
begin
......从数据库取值,代码省略
query_cx.Next;
end;
//--查询结束----------------------------------------------------------------//
if bz = false then
begin
send('','0','1111','101',athread); //自定义函数
bz:=true;
end
else
begin
if zje<0 then //总金额小于零
begin
send('','0','1111','101',athread);
end
else if zje = 0 then
begin
send('','0','1111','100',athread);
end
else
begin
cnt := query_cx.RecordCount;
if sfbz='0' then
begin
send_cmd := yhbh + '|' + yhxm + '|' + yhdz + '|' + floattostr(sfmj)
+ '|' + floattostr(zje)+ '|' +inttostr(cnt)+ '|4'+ fyxx;
send(send_cmd,'0','1111','000',athread); //发送数据,自定义函数
end
else
begin
send('','0','1111','101',athread);
end;
end;
end;
end;
//end if--------------------------------------------------------------------//
athread.Connection.InputBuffer.Clear; //清接收缓冲区
exit;
end;
procedure tform1.sf(yhbh:String;lsh:string;skje:string;jysj_date:string;jysj_time:string;athread:tidpeerthread);
var
变量定义,省略。。。。。。。
begin
qqls('2222',yhbh,lsh);
//----向console输出信息---------------------------------------------------//
console.Lines.Add(datetimetostr(now()) + ' ' + '客户端收费请求! IP地址: '
+ athread.Connection.Socket.Binding.PeerIP + ' 收费用户编号:' + yhbh);
//----进行查询------------------------------------------------------------//
query_sf.Close;
query_sf.Parameters.ParamByName('yhbh').Value := trim(yhbh);
if query_sf.Prepared=false then query_sf.Prepared;
query_sf.Open;
if query_sf.RecordCount=0 then //如果记录为0-------------------//
begin
send('','0','2222','100',athread);
end
else//如果有数据
begin
while not query_sf.Eof do
begin
.....从数据库取值,代码省略
query_sf.Next;
end;
//--查询结束----------------------------------------------------------------//
.........
sfls.CommandText:=inssql;
try
begin
sfls.Execute;
send(send_cmd,'0','2222','000',athread); //发送数据
end;
except //如果操作数据库异常,则向银行发送收费交易错误代码200
begin
send(send_cmd,'0','2222','200',athread);
end;
end;
end;
end;
end;
//----记流水帐函数------------------------------------------------------------//
function TForm1.qqls(jydm, yhbh: string;lsh:string): boolean;
var
sql:string;
begin
ins_ls.Parameters.ParamByName('jydm').Value:= jydm;
ins_ls.Parameters.ParamByName('jysj').Value:=now();
ins_ls.Parameters.ParamByName('yhbh').Value:= yhbh;
sql:= ins_ls.CommandText;
ins_ls.Execute;
end;
//----发送数据函数,加入消息头并发发送数据-------------------------------------//
procedure TForm1.send(cmd: string; flag:string;code:string;reply:string;athread: tidpeerthread);
var
send_cmd:string;
temp_cmd:string;
begin
if athread.Connection.Connected then
begin
if length(trim(cmd))>0 then
begin
cmd:= '|' + flag + '|' + code + '|' + reply + '|' + cmd +'|';
send_cmd := formatfloat('00##',length(cmd)) + cmd //组织要传送的数据
end
else
begin
cmd:= '|' + flag + '|' + code + '|' + reply + '|';
send_cmd := formatfloat('00##',length(cmd)) + cmd ; //组织要传送的数据
end;
athread.Connection.Write(send_cmd); //发送数据
console.Lines.Add(datetimetostr(now()) + ' ' + '响应客户端请求! IP地址: '
+ athread.Connection.Socket.Binding.PeerIP );
console.Lines.add(' 服务器发送数据包: ' + send_cmd);
end
else
begin
console.Lines.Add('连接已经断开!无法发送数据...');
exit;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
console.Lines.Clear;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
server.DefaultPort:=9999;
server.Active:=true;
console.Lines.Add(datetimetostr(now()) + ' 正在监听端口6666......');
console.SetFocus;
end;
procedure TForm1.serverException(AThread: TIdPeerThread;
AException: Exception);
begin
console.Lines.Add('System Exception message: ' + aexception.Message);
end;
procedure TForm1.serverDisconnect(AThread: TIdPeerThread);
begin
console.Lines.Add('disconnected.....');
end;
initialization
// 初始化线程同步对象
cscx:=tcriticalsection.Create;
cssf:=tcriticalsection.Create;
cszx:=tcriticalsection.Create;
cscd:=tcriticalsection.Create;
is_first:=true;
end.
运行一段时间后,会出错误,具体表现是当客户端再发请求过来的时候,服务端能看到(MEMO上的输出信息),但是不能响应客户端了,就是不会发送数据了。。
水平有限,实在找不出原因了,麻烦大家帮忙看看什么问题。