如何在线程的中创建TClientSocket对象从服务器读取数据

yanier 2008-11-19 02:15:45
季老大能否告诉我如何在线程中创建TClientSocket对象从服务器读取数据1
我要作的程序作客户端,主要功能是从下位机读取数据并进行数据处理,下位机做服务器采集数据并在得到上位机读数指令时将采集数据上传客户端。客户端我想在线程中创建TClientSocket对象用于读取服务器的数据。问题是1、在线程的Execute中怎么创建TClientSocket;2、创建后怎么读取数据
...全文
133 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
僵哥 2008-11-20
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 yanier 的回复:]
to yuanreid
void __fastcall TXXXX::OnConnect(System::TObject* Sender, TCustomWinSocket* Socket)
这是放在线程中吗?我只知道非阻塞模式消息会触发TClientSocket的OnConnect事件,线程里怎样实现呢
[/Quote]
除了OnRead/OnWrite事件以外的事件都会触发。
yanier 2008-11-20
  • 打赏
  • 举报
回复
to yuanreid
void __fastcall TXXXX::OnConnect(System::TObject* Sender, TCustomWinSocket* Socket)
这是放在线程中吗?我只知道非阻塞模式消息会触发TClientSocket的OnConnect事件,线程里怎样实现呢
yanier 2008-11-20
  • 打赏
  • 举报
回复
呵呵,认真学习!
yuanreid 2008-11-20
  • 打赏
  • 举报
回复
下面的就是帮助中的例子。



void __fastcall TMyServerThread::ClientExecute(void)

{
TWinSocketStream *pStream;
char Buffer[10];
// make sure connection is active
while (!Terminated && ClientSocket->Connected)
{
try
{
Stream = new TWinSocketStream(ClientSocket, 60000);
try
{
memset(Buffer, 0, 10); // initialize the buffer
// give the client 60 seconds to start writing
if (pStream->WaitForData(60000))
{
if pStream->Read(Buffer, 10) == 0) // if can抰 read in 60 seconds

ClientSocket->Close(); // close the connection
// now process the request
...
}
else
ClientSocket->Close(); // if client doesn抰 start, close
}
__finally
{
delete pStream;
}
}
catch (Exception &E)
{
HandleException();
}
}
}
yuanreid 2008-11-20
  • 打赏
  • 举报
回复
我用的就是阻塞模式,跟在哪里有关系吗?为什么就不愿意去查一下帮助呢!编程岂不没有乐趣了。

创建:
ClientSocket = new TClientSocket(this);
ClientSocket->Host = "127.0.0.1";
ClientSocket->Port = 6200;
ClientSocket->ClientType = ctBlocking;
ClientSocket->OnConnect = OnConnect;
ClientSocket->OnError = OnError;
创建TWinSocketStream
void __fastcall TXXXX::OnConnect(System::TObject* Sender, TCustomWinSocket* Socket)
{
SP_CHECKPOINT;
SocketStream = new TWinSocketStream(Socket, 5000);
SocketTimer->Enabled = true;
}

读取的刚才有了。

发送:
int length = SocketStream->Write(SendBuf, sizeof(TCommandHead)+sizeof(CBODY_Initialize));
yanier 2008-11-20
  • 打赏
  • 举报
回复
to yuanreid
不是这样的,我要学习ClientSocket阻塞模式的例子,比如form中某Button的Click中创建线程,而在线程Execute中动态创建Cliensocket(如1楼僵哥所示),现在的问题是,线程中创建Cliensocket后怎么读写
yuanreid 2008-11-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 yanier 的回复:]
那位有ClientSocket阻塞模式的例子,借来学习下,zhangwy_xh@163.com
[/Quote]
阻塞方式可以看BCB的帮助。顺便查看一下TWinSocketStream会对你有帮助。


void __fastcall TXXXX::SocketOnTimer(System::TObject* Sender)
{
if(ClientSocket->Socket->Connected == false) return;
if(SocketStream->WaitForData(10)) //设置等待数据超时时间,如果你是在线程中,可以通过while循环来检查
{
char RecvBuf[4096];
memset(RecvBuf, 0, sizeof(RecvBuf));
int recvlen = SocketStream->Read(RecvBuf, sizeof(RecvBuf));
SP_LOGINFO(__FUNC__, "接收字节 [ "+IntToStr(recvlen)+" ]");

if(recvlen<=0)
{
SP_LOGINFO(__FUNC__, "连接关闭");
SocketTimer->Enabled = false;
if(SocketStream)
delete SocketStream;
SocketStream = NULL;

ClientSocket->Active = false;
FActived = false;
return;
}

if(recvlen < sizeof(ThirdPartyEventHead))
{
SP_LOGERROR(__FUNC__, "接收字节小于包头大小,放弃");
return;
}
int readlen = 0;
char* recvbuf = RecvBuf;
while(readlen<recvlen)
{
recvbuf = recvbuf + readlen;
recvlen = recvlen - readlen;
readlen = DoEventMsg(recvbuf, recvlen, ClientSocket->Socket);
}
}
}
yanier 2008-11-20
  • 打赏
  • 举报
回复
那位有ClientSocket阻塞模式的例子,借来学习下,zhangwy_xh@163.com
yanier 2008-11-20
  • 打赏
  • 举报
回复
我想知道把Client->ClientType设为ctBlocking阻塞后,要在那里读取服务器发来的数据能?也就是在什么事件、方法内读写数据
yanier 2008-11-19
  • 打赏
  • 举报
回复
谢谢僵哥,我先down下看看
僵哥 2008-11-19
  • 打赏
  • 举报
回复
个人建议使用OverByte的ICS套件当中的WSocket,本身就有实现MessageLoop比TClientSocket使用起来就相对简单很多。可以到官网(http://www.overbyte.be)或者到我的资源(http://download.csdn.net/source/590284)当中下载。
BCBPLC 2008-11-19
  • 打赏
  • 举报
回复
线程这东东在VCL中少用
僵哥 2008-11-19
  • 打赏
  • 举报
回复
class  MyThread :public TThread{
Protected:
void __fastcall Execute(void);
};

void __fastcall MyThread::Execute(void)
{
TClientSocket *Client= new TClientSocket(NULL);
try{
Client->Address = "192.168.10.1";
Client->Port = 80;
Client->ClientType = ctBlocking;//不能使用消息,所以不会有事件通知,只能使用Blocking模式
Client->Open();
...
}__finally{
Client->Free();
}
}

否则的话,需要在线程当中执行MessageLoop.

13,825

社区成员

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

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