BCB6用ClientSocket进行短连接式查询,有没有优雅的方法?

fangrk 2006-01-14 11:04:18
如题。
以前从网上看到的并且现在在使用的方法是:
用ClientSocket->Active=true;来触发

然后在ClientSocketConnect中发送查询包,比如:
void __fastcall TMainForm::ClientSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString Account=AccBalanceGrid->Cells[0][AccLine];
if(Account.Length()>19){
ShowMessage("Account.Length()>19!");
return;
}
AnsiString SendPack=AnsiString("00351010-4343-552")+
AnsiString::StringOfChar(' ',19-Account.Length())+
Account+"001";

if(ClientSocket1->Socket->Connected ){
ClientSocket1->Socket->SendText(SendPack);
}


}

然后在ClientSocketOnRead中接受返回包,比如:
void __fastcall TMainForm::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString ReceivePack=Socket->ReceiveText();
AccBalanceGrid->Cells[1][AccLine]=ReceivePack;
}

我现在遇到的问题是,如果要连续执行查询那么必须在ClientSocketOnRead中再次触发,比如:
void __fastcall TMainForm::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString ReceivePack=Socket->ReceiveText();
AccBalanceGrid->Cells[1][AccLine]=ReceivePack;
//为了再次查询
ClientSocket->Active=false;
ClientSocket->Active=true;
}

这样的代码我觉得比较丑陋而且容易出错,请教各位能否把查询做成一个函数来单独调用,比如查询函数原形为:
void Query(const AnsiString& SendPack,AnsiString& ReceivePack);

然后在某个地方就这样调用:
for(int i=1;i<Grid->RowCount;++i){
AnsiString Send=.....;
AnsiString Receive;
Query(Send,Receive);
......
}
...全文
198 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
痞子酷 2006-01-17
  • 打赏
  • 举报
回复
int ConnectSocket(char *strSvrIP,int iSvrPort)
{
SOCKADDR Socket_Addr;
SOCKADDR_IN Socket_Addr_in;

WORD Version =0x0002;
WSADATA WSDATA;
WSAStartup(Version,&WSDATA);

//创建SOCKET
m_clientSockect=socket(AF_INET,1,0);
if(m_clientSockect==INVALID_SOCKET){
return -1;
}
Socket_Addr_in.sin_family=AF_INET;
Socket_Addr_in.sin_port=htons(iSvrPort);
Socket_Addr_in.sin_addr.s_addr=inet_addr(strSvrIP);
memcpy(&Socket_Addr,&Socket_Addr_in,sizeof(SOCKADDR_IN));

//建立连接
if (connect(m_clientSockect,(struct sockaddr *)&Socket_Addr,sizeof(Socket_Addr))!=0 ){
return -2;
}

closesocket(m_clientSockect);
WSACleanup();
return 0
}
sunxiaohui 2006-01-17
  • 打赏
  • 举报
回复
使用阻塞方式.
clientsocket1->clienttype 应是ctblocking
以下代码供参考。

AnsiString Recv_Str;
char recv_str[2048];
int ret;

pStream = new TWinSocketStream(ClientSocket1->Socket,Time_Out.ToInt());
ClientSocket1->Address =Edit2->Text;
ClientSocket1->Port =Edit3->Text.ToInt();
try
{
ClientSocket1->Active =true;
}
catch(Exception &E)
{
ShowMessage("连接服务器失败!");
return;
}

ret=pStream->Write(Send_Data->Text.c_str(),Send_Data->Text.Length());
if (ret != Send_Data->Text.Length())
{
ClientSocket1->Active =false;
ShowMessage("发送数据失败!");
return;
}
RichEdit2->Lines->Add("发送的数据长度:"+IntToStr(ret));

memset(recv_str,0,sizeof(recv_str));
if (pStream->WaitForData(Time_Out.ToInt()))
{
ret = pStream->Read(recv_str,2048);
if(ret<=0)
{
ClientSocket1->Active =false;
ShowMessage("接收数据失败!");
return;
}
}
else
{
ClientSocket1->Active =false;
ShowMessage("接收数据超时!");
return;
}

ClientSocket1->Active =false;
Recv_Str=recv_str;
if(Recv_Str.IsEmpty())
{
RichEdit2->Lines->Add("接收数据为空!");
}
else
{
RichEdit2->Lines->Add("接受的数据长度为:"+IntToStr(Recv_Str.Length()));
RichEdit2->Lines->Add(Recv_Str);
}
RichEdit2->SetFocus();
RichEdit2->Perform(EM_SCROLLCARET,0,0);
netsys2 2006-01-16
  • 打赏
  • 举报
回复
可以,直接用SOCKET API写。
zjsyw 2006-01-16
  • 打赏
  • 举报
回复
为什么要这么用
rxiao99 2006-01-15
  • 打赏
  • 举报
回复
要用阻塞方式吧!

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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