(中行雷威2018.3.10)
(同一个世界,同一个梦想,交流学习C++Builder XE10,传承c++builder的魅力!欢迎各地朋友加入我的QQ群484979943,进群密码“BCB”,同时也请将该群号广为宣传,希望能够广集各方高手,共同进步。如需下载开发工具及源代码请加入我的QQ群)
【阅读倡议】
1、有问题请留言;
2、没问题请点赞;
3、看连载请加群;
4、下源码请加群;
【开发工具】
1、C++Builder10.2.2tokyo
2、FMSoft_uniGUI_Complete_Professional_1.0.0.1424_Trial
本文将简单介绍如何在uniGUI下使用indy通讯控件IdTCPClient开发一个WEB通讯应用,通过该应用向远程服务器发送和接受报文。通讯方式为同步短连接,即有发送需求就建立连接,连接上就发送,发送完就关闭。
一、创建项目
主菜单File-》New-》Other选择uniGUI for C++Builder创建项目
选择Yes.完成项目创建。
主菜单:设置Project-》Options设置Include path和Library path,分别都添加C:\Program Files (x86)\Embarcadero\Studio\19.0\uniGUI目录
Linker和Runtime Packages取消动态链接和引用动态包
二、主窗口设计
在主窗口MainForm上摆放两个UniEdit控件,一个设置远程服务器地址,一个设置远程服务器端口;摆放两个UniMemo控件,一个用于配置发送出去的报文,一个用于显示接收到的报文;摆放三个UniBitBtn控件,一个用于连接远程服务器,一个用于发送报文,一个用于断开通讯;摆放一个IdTCPClient控件用于通讯;摆放一个UniTimer控件,用于监测远程服务器的返回报文。
三、代码设计
1、UniBitBtn1按钮添加OnClick事件实现连接远程服务器
void __fastcall TMainForm::UniBitBtn1Click(TObject *Sender)
{
//连接
IdTCPClient1->Host=UniEdit1->Text;
IdTCPClient1->Port=UniEdit2->Text.ToInt();
if(!IdTCPClient1->Connected())
{
try
{
IdTCPClient1->Connect();
}
catch(...)
{
ShowMessage("连接失败!");
}
}
else
{
ShowMessage("已经连接成功!");
}
}
同时,在IdTCPClient的OnConnect事件和OnDisconnect事件中添加代码,显示连接和断开结果。
void __fastcall TMainForm::IdTCPClient1Connected(TObject *Sender)
{
ShowMessage("连接成功!");
}
void __fastcall TMainForm::IdTCPClient1Disconnected(TObject *Sender)
{
ShowMessage("断开成功!");
}
2、UniBitBtn3按钮添加OnClick事件实现断开与远程服务器的连接
void __fastcall TMainForm::UniBitBtn3Click(TObject *Sender)
{
//断开
IdTCPClient1->Disconnect();
}
3、UniBitBtn2按钮添加OnClick事件实现向远程服务器发送报文
void __fastcall TMainForm::UniBitBtn2Click(TObject *Sender)
{
UniBitBtn1->Click();//发送报文前先调用连接按钮事件确保已经连接再发送
AnsiString sendMsg;
TByteDynArray sendArray;
char sendBuf[1024];
sendMsg=UniMemo1->Text;
memset(sendBuf,'\0',1024);
sprintf(sendBuf,"%s",sendMsg);
sendBuf[sendMsg.Length()]='\n';
sendArray=Uidglobal::RawToBytes(static_cast<void*>(sendBuf),sendMsg.Length());
if(!IdTCPClient1->Connected())
{
return;
}
IdTCPClient1->Socket->Write(sendArray,sendMsg.Length(),0);//发送报文
}
4、UniTimer1的OnTimer事件配置接收报文代码
void __fastcall TMainForm::UniTimer1Timer(TObject *Sender)
{
AnsiString recvMsg;
TByteDynArray recvArray;
char recvBuf[1024];
Uidglobal::TIdBytes recvBytes; /*该变量不知道为啥不能放到程序头部定义,在这个函数里定义却没有问题*/
if(!IdTCPClient1->Connected())
return;
if(IdTCPClient1->Socket->InputBuffer->Size>0)//判断输入缓冲区是否有内容要接收
{
IdTCPClient1->Socket->ReadBytes(recvBytes,IdTCPClient1->Socket->InputBuffer->Size,true);//接收报文
recvMsg=StringOf(recvBytes);
memset(recvBuf,'\0',1024);
for(int m=0;m<recvMsg.Length();m++)//此段为接收到报文的格式化,一般能正常显示的GBK报文接收用不到,但是如果返回无法显示的特殊计算机代码则可能导致接收报文显示时候断开,此时需要配置。
{
sprintf(&recvBuf[m],recvMsg.SubString(m+1,1).c_str(),1);
if((int)recvBuf[m]>=0 && (int)recvBuf[m]<=31) //为正常显示,将导致字符串中断的字符‘ascii=0’替换为‘.’
{
recvMsg[m+1]='.';
}
}
//格式化显示
UniMemo2->Lines->Add(recvMsg);
UniBitBtn3->Click();//接收完就调用断开按钮断开与服务器的连接。
}
}
四、运行效果
在浏览器中输入http://127.0.0.1:8077打开项目主界面,本例中我启动了一个我开发的交易测试模拟器作为服务端,运行结果如下:
1、本例新开发的客户端
2、配合测试的服务端
五、后记
经测试,运行稳定!Indy是开发工具C++builder 10.2.2 tokyo自带的通讯组件,本例证明,Indy系列通讯控件在UniGUI下能够正常使用。本例中用于模拟服务端的通讯模拟器是本人的开发作品,在某银行已经使用多年,加速了多个项目的模拟测试,如有兴趣,请加入我的QQ群,在文件共享"A01-我的开发作品"里找用户手册和产品介绍。