用idtcpclient和服务器通讯会出现“connection closed gracefully”,求大神帮忙分析下,源码如下:

qq_31343629 2015-09-22 03:22:22
用idtcpclient和服务器通讯会出现“connection closed gracefully”,基本流程是客户端向服务器发数据,服务器执行完操作后将数据返回。
求大神帮忙分析下,源码如下:


void __fastcall TfmTimerReadOne::Timer2Timer(TObject *Sender)
{
byte Recive_Datas[76];
//--------------接收程序-----------------------------------
if(IdTCPClient1->Connected()){
while(!IdTCPClient1->IOHandler->InputBufferIsEmpty())
{
byte Date;
Date= IdTCPClient1->IOHandler->ReadByte();
if(Date!=0xFF){
Recive_Datas[i]=Date; //只接受76位
i++;
}
if((Recive_Datas[0]==0xAF)&&(Recive_Datas[1]==0xBF)&&//判断是否接受到了DTU返回数据头和尾
(Recive_Datas[2]==0xCF)&&(Recive_Datas[3]==0xDF)&& //如果判断数据为DTU返回数据,则返回给PC客户端
(Recive_Datas[i-1]==0xFD)&&(Recive_Datas[i-2]==0xFC)&&
(Recive_Datas[i-3]==0xFB)&&(Recive_Datas[i-4]==0xFA)){
//------解析数据---------------------------------
AnsiString Meter_ID_H;//当前所读表地址高位
AnsiString Meter_ID_L;//当前所读表地址低位
AnsiString Meter_ID;
AnsiString Now_Heat;//当前热量
AnsiString Now_Flow;//瞬时流量
AnsiString Cum_Flow;//累计流量
AnsiString In_Temp;//进水温度
AnsiString Out_Temp;//出水温度
AnsiString Cum_WorkingTime;//累计工作时间
AnsiString differentTemp;//温度差
Meter_ID_H=AddZero(BCD_(Recive_Datas[19]))+AddZero(BCD_(Recive_Datas[18]))+AddZero(BCD_(Recive_Datas[17]));
Meter_ID_L=AddZero(BCD_(Recive_Datas[16]))+AddZero(BCD_(Recive_Datas[15]))+AddZero(BCD_(Recive_Datas[14]))+AddZero(BCD_(Recive_Datas[13]));
Meter_ID= Meter_ID_H+ Meter_ID_L;
Now_Heat=IntToStr((BCD_(Recive_Datas[32]))+(BCD_(Recive_Datas[33]))*100+(BCD_(Recive_Datas[34]))*10000)+'.'+(BCD_(Recive_Datas[31]));//当前热量
Now_Flow=IntToStr((BCD_(Recive_Datas[44]))*100)+IntToStr((BCD_(Recive_Datas[43])))+'.'+IntToStr((BCD_(Recive_Datas[42]))+(BCD_(Recive_Datas[41])/100));//瞬时流量
Cum_Flow=IntToStr((BCD_(Recive_Datas[49]))*10000)+IntToStr((BCD_(Recive_Datas[48]))*100)+IntToStr((BCD_(Recive_Datas[47])))+'.'+IntToStr((BCD_(Recive_Datas[46])));//累计流量
In_Temp=IntToStr((BCD_(Recive_Datas[52]))*100+(BCD_(Recive_Datas[51])))+'.'+IntToStr(BCD_(Recive_Datas[50])); //进水温度
Out_Temp=IntToStr((BCD_(Recive_Datas[55]))*100+(BCD_(Recive_Datas[54])))+'.'+IntToStr(BCD_(Recive_Datas[53])); //出水温度
Cum_WorkingTime=IntToStr((BCD_(Recive_Datas[58]))*10000+(BCD_(Recive_Datas[57]))*100+BCD_(Recive_Datas[56])) ; //累计工作时间
float fdifferentT = StrToFloat(In_Temp)-StrToFloat(Out_Temp);
differentTemp= FormatFloat("0.00",fdifferentT); //进出口温差
AnsiString year = IntToStr(BCD_(Recive_Datas[59])*100+ BCD_(Recive_Datas[60]));//年
AnsiString month = IntToStr(BCD_(Recive_Datas[61])); //月
AnsiString day = IntToStr(BCD_(Recive_Datas[62])); //日
AnsiString hour = IntToStr(BCD_(Recive_Datas[63])); //时
AnsiString minute = IntToStr(BCD_(Recive_Datas[64]));//分
AnsiString second = IntToStr(BCD_(Recive_Datas[65])); //秒
AnsiString Read_Time =year + "-" + month + "-" + day + " " + hour + ":" +minute + ":" + second;
AnsiString BatteryState;
if(Recive_Datas[66]==0x04){ //电池是否欠压
BatteryState="欠压";
}
else{
BatteryState="正常";
}
//---------解析完成------------------------------
AnsiString stry;
AnsiString strm;
AnsiString strd;
AnsiString strh;
AnsiString strmin;
AnsiString strs;
AnsiString strsystime;
SYSTEMTIME *GT=new SYSTEMTIME; // 系统时间变量
GetLocalTime(GT); //提取本地时间
stry = AnsiString(GT->wYear);
strm = AnsiString(GT->wMonth);
strd = AnsiString(GT->wDay);
strh = AnsiString(GT->wHour);
strmin = AnsiString(GT->wMinute);
strs = AnsiString(GT->wSecond);
strsystime = stry + "/" + strm + "/" + strd + " " + strh + ":" +strmin + ":" + strs; //system time in strsystime
AnsiString mysql;
TADOQuery *Query = new TADOQuery(this);
Query->Connection=fmMain->ADOConnection1;
Query->SQL->Clear();
Query->SQL->Add("select MeterNumber,LastRead from ylt.ResidentMeterRead where MeterNumber='"+Meter_ID+"'");
Query->Open();
float Heat=StrToFloat(Now_Heat)-StrToFloat(Query->FieldByName("LastRead")->AsString);
AnsiString HeatDiffence=FormatFloat("0.00",Heat);
if(CheckBox1->Checked==true){
mysql="UPDATE ylt.ResidentMeterRead SET CurrentRead = '"+Now_Heat+"',InstantaneousFlow ='";
mysql+=Now_Flow+"',CumulativeFlow ='"+Cum_Flow+"',InletTemperature ='"+In_Temp+"',EffluentTemperature='";
mysql+=Out_Temp+"',ReadMeterMark='成功',Heat='"+HeatDiffence+"',BatteryState='"+BatteryState+"',Runtime ='";
mysql+=Cum_WorkingTime+"',ReadingDate='"+strsystime+"'";
mysql+=" WHERE MeterNumber = '"+Meter_ID+"'";
}
else{
mysql="UPDATE ylt.ResidentMeterReadTemple SET CurrentRead = '"+Now_Heat+"',InstantaneousFlow ='";
mysql+=Now_Flow+"',CumulativeFlow ='"+Cum_Flow+"',InletTemperature ='"+In_Temp+"',EffluentTemperature='";
mysql+=Out_Temp+"',ReadMeterMark='成功',Heat='"+HeatDiffence+"',BatteryState='"+BatteryState+"',Runtime ='";
mysql+=Cum_WorkingTime+"',ReadingDate='"+strsystime+"'";
mysql+=" WHERE MeterNumber = '"+Meter_ID+"'";
}
Query->Close();
Query->SQL->Clear();
Query->SQL->Add(mysql); //将数据更新到数据库中
Query->ExecSQL();
delete Query;
Query=NULL;
ReadSuccess=true;
for(int n=0;n<76;n++){
Recive_Datas[n]=0x0;
}
i=0;
}
}
}
//-------------SC解析程序结束--------------------------------
}
//---------------------------------------------------------------------------
void __fastcall TfmTimerReadOne::GPRSReadMeter(AnsiString MeterAddress,AnsiString TABLE)//GPRS读表函数
{
if(IdTCPClient1->Connected()==false){
TADOQuery *pq= new TADOQuery(this);
pq->Connection=fmMain->ADOConnection1;
pq->SQL->Clear();
pq->SQL->Add("select IP,Port from ServerSet where TYPE='服务器'");
pq->Open();
IdTCPClient1->Host=pq->FieldByName("IP")->AsString;
IdTCPClient1->Port=StrToInt(pq->FieldByName("Port")->AsString);
IdTCPClient1->Connect();
}
unsigned short crc_value;//存放CRC检验结果
TADOQuery *pMeterReadCard = new TADOQuery(Application);
pMeterReadCard->Connection=fmMain->ADOConnection1;
pMeterReadCard->SQL->Clear();
pMeterReadCard->SQL->Add("select DTUNumber from ylt."+TABLE+" where MeterNumber = '"+MeterAddress+"'");
pMeterReadCard->Open();
AnsiString CardNo = pMeterReadCard->FieldByName("DTUNumber")->AsString;//与表号对应的采集器编号
pMeterReadCard->Close();
delete pMeterReadCard;
TADOQuery * pMeterReadChannel = new TADOQuery(Application);
pMeterReadChannel->Connection=fmMain->ADOConnection1;
pMeterReadChannel->SQL->Clear();
pMeterReadChannel->SQL->Add("select DTUChannel from ylt."+TABLE+" where MeterNumber = '"+MeterAddress+"'");
pMeterReadChannel->Open();
AnsiString ChannelNo = pMeterReadChannel->FieldByName("DTUChannel")->AsString;//与表号对应的通道号
pMeterReadChannel->Close();
delete pMeterReadChannel;
byte comm[39]; //发送数据数组
comm[0] = 0x0A;
comm[1] = 0x0D;
comm[2] = 0x01;
comm[3] = 0x33;
comm[4] = 0xAF;
comm[5] = 0xBF;
comm[6] = 0xCF;
comm[7] = 0xDF;
comm[8] = 0x01;
comm[9] = StrToInt("0x"+CardNo.SubString(1,2));
comm[10]= StrToInt("0x"+CardNo.SubString(3,2));
comm[11]= 0x00;
comm[12]= 0x18;
comm[13]= 0xFE;
comm[14]= 0xFE;
comm[15]= 0x68;
comm[16]= 0x20;
comm[17]= StrToInt("0x"+MeterAddress.SubString(13,2));
comm[18]= StrToInt("0x"+MeterAddress.SubString(11,2));
comm[19]= StrToInt("0x"+MeterAddress.SubString(9,2));
comm[20]= StrToInt("0x"+MeterAddress.SubString(7,2));
comm[21]= StrToInt("0x"+MeterAddress.SubString(5,2));
comm[22]= StrToInt("0x"+MeterAddress.SubString(3,2));
comm[23]= StrToInt("0x"+MeterAddress.SubString(1,2));
comm[24]= 0x01;
comm[25]= 0x03;
comm[26]= 0x90;
comm[27]= 0x1F;
comm[28]= 0x01;
comm[29]= 0x00;
comm[30]= 0x16;
crc_value=CRC16(comm+8,23); //进行CRC检验
comm[31]= crc_value%256;
comm[32]= crc_value/256;
comm[33]= 0xFA;
comm[34]= 0xFB;
comm[35]= 0xFC;
comm[36]= 0xFD;
comm[37]= 0x0B;
comm[38]= 0x0C;
i=0;
Timer2->Enabled=true;
for(int i=0;i<39;i++){
try{
IdTCPClient1->IOHandler->Write(comm[i]);
}
catch(...){
if(IdTCPClient1->Connected()==false){
TADOQuery *pq= new TADOQuery(this);
pq->Connection=fmMain->ADOConnection1;
pq->SQL->Clear();
pq->SQL->Add("select IP,Port from ServerSet where TYPE='服务器'");
pq->Open();
IdTCPClient1->Host=pq->FieldByName("IP")->AsString;
IdTCPClient1->Port=StrToInt(pq->FieldByName("Port")->AsString);
IdTCPClient1->Connect();
delete pq;
pq=NULL;
}
IdTCPClient1->IOHandler->Write(comm[i]);
}
}
DWORD Start = GetTickCount();
while(GetTickCount()-Start < 1000*5){ //等3秒
Application->ProcessMessages();//保证在延时期间程序可以相应oncomm事件
}
Timer2->Enabled=false;
IdTCPClient1->Disconnect();
}
...全文
1775 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
netying 2015-09-23
  • 打赏
  • 举报
回复
可以重试,直到成功为止。应该没什么影响。
qq_31343629 2015-09-22
  • 打赏
  • 举报
回复
发送程序上面写不下了,所以就副到这里了,很奇怪的是这个错误不是总出现,而是有时候出现,有时候不出现,还无法定位,所以只有求助各位大神了

void __fastcall TfmTimerReadOne::PrepareRead()
{
	TfmLoading *fmLoading = new TfmLoading(Application);
	fmLoading->Position=poScreenCenter;
	fmLoading->Show();
	fmLoading->Update();
	if(IdTCPClient1->Connected()==false){
	try{
	TADOQuery *pq= new TADOQuery(this);
	pq->Connection=fmMain->ADOConnection1;
	pq->SQL->Clear();
	pq->SQL->Add("select IP,Port from ServerSet where TYPE='服务器'");
	pq->Open();
	IdTCPClient1->Host=pq->FieldByName("IP")->AsString;
	IdTCPClient1->Port=StrToInt(pq->FieldByName("Port")->AsString);
	IdTCPClient1->Connect();
	}
	catch(...){
		Application->MessageBoxW(L"连接服务器失败,请检查网络!",L"失败",MB_OK);
		BitBtn2->Enabled=true;
		DBGrid1->Enabled=true;
		delete fmLoading;
		return;
	}
	}
	if(ADOQuery1->RecordCount==0){
		delete fmLoading;
		Application->MessageBoxW(L"表中无记录",L"消息",MB_OK);
		BitBtn2->Enabled=true;
		return;
	}
        ADOQuery1->First();
		int faultnumber=0;
		int querynumber=0;
		for(int i =0;i<ADOQuery1->RecordCount;i++){
				int jishuqi=0;
				ReadSuccess=false;
				querynumber++;
				Label1->Caption="抄表总数:"+IntToStr(querynumber);
				while(ReadSuccess!=true){
				GPRSReadMeter(ADOQuery1->FieldByName("表号")->AsString.Trim(),"ResidentMeterRead");
				if(jishuqi==5){
				jishuqi=0;
				faultnumber++;
				Label2->Caption="抄表失败:"+IntToStr(faultnumber);
				TADOQuery *Exception=new TADOQuery(this);
				Exception->Connection=fmMain->ADOConnection1;
				Exception->SQL->Clear();
				if(CheckBox1->Checked==true){
				Exception->SQL->Add("update ylt.ResidentMeterRead set ReadMeterMark ='失败' where MeterNumber='"+ADOQuery1->FieldByName("表号")->AsString.Trim()+"'");
				}
				else {
				Exception->SQL->Add("update ylt.ResidentMeterReadTemple set ReadMeterMark ='失败' where MeterNumber='"+ADOQuery1->FieldByName("表号")->AsString.Trim()+"'");
				}
				Exception->ExecSQL();
				delete Exception;
				break;
				}
				jishuqi++;
				}
			ADOQuery1->Next();
		}
	DBGrid1->Enabled=true;
	ADOQuery1->Close();
	ADOQuery1->SQL->Clear();
	AnsiString sql;
	if(CheckBox1->Checked==true){
	sql="select MeterNumber as 表号,DTUNumber as 集抄器号,DTUChannel 集抄器通道号,ResidentNumbe as 编码";
	sql+=",CommunityName as 小区名称,BuildingName as 栋号,UnitName as 单元号,RoomName as 房间号,ResidentName as 用户名称,UserType as 用户类型,Area as 面积,LastRead as 上次底数, ";
	sql+="CurrentRead as 本次底数,ReadMeterMark 是否抄表,Succeed 是否成功,Heat as 用热量,";
	sql+="CumulativeFlow as 累计流量,InstantaneousPower as 瞬时功率,InstantaneousFlow as 瞬时流量,Runtime as 运行时间,";
	sql+="FaultCondition as 故障状态,InletTemperature as 进水温度,EffluentTemperature as 回水温度,BatteryState as 电池状态,ReadingDate as 抄表日期";
	sql+=" from ylt.ResidentMeterRead where FaultCondition<>'故障' ";
	}
	else {
	sql="select MeterNumber as 表号,DTUNumber as 集抄器号,DTUChannel 集抄器通道号,ResidentNumbe as 编码";
	sql+=",CommunityName as 小区名称,BuildingName as 栋号,UnitName as 单元号,RoomName as 房间号,ResidentName as 用户名称,UserType as 用户类型,Area as 面积,LastRead as 上次底数, ";
	sql+="CurrentRead as 本次底数,ReadMeterMark 是否抄表,Succeed 是否成功,Heat as 用热量,";
	sql+="CumulativeFlow as 累计流量,InstantaneousPower as 瞬时功率,InstantaneousFlow as 瞬时流量,Runtime as 运行时间,";
	sql+="FaultCondition as 故障状态,InletTemperature as 进水温度,EffluentTemperature as 回水温度,BatteryState as 电池状态,ReadingDate as 抄表日期";
	sql+=" from ylt.ResidentMeterReadTemple where FaultCondition<>'故障' ";
    }
	ADOQuery1->SQL->Add(sql);
	ADOQuery1->Open();
	delete fmLoading;
}
缘中人 2015-09-22
  • 打赏
  • 举报
回复
是服务端断开了。

1,316

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧