请教:IDTCPClient组件应用的问题!

xinxin_2006 2006-11-17 10:05:52
请教一个问题,各位知道的请多多帮忙!!
IDTCPClient组件在应用的时候,要用到readbuffer()这个函数去读取服务器端口发来的数据,可是:我不明白的一点,也就是IDtcpclient客户端何时知道服务器端给它发来数据,然后调用readbuffer()函数呢?(IDTCPClient函数中有没有哪个事件能完成这个功能:就是一旦检测到服务器端发来数据,就能立即调用readbuffer 这个函数!)

...全文
631 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
daily66 2007-03-24
  • 打赏
  • 举报
回复
顶了
n27741 2007-02-26
  • 打赏
  • 举报
回复
这几天过年脑袋睡晕了
更正一下
ReadBuffer(void *p ,unsige size);
接收到回执信息
如果没有接收到返回-1
并不堵塞.是我记忆错误
那么堵塞这个线程很容易了
while(ReadBuffer(void *p ,unsige size)<=0)
{
Sleep(10);
}
那么客户端就一直等待服务器的反馈了
否则就不执行
不需要去侦听onRead事件
不好意思啊 今天翻代码才回忆起来的 :)
sczyq 2007-02-25
  • 打赏
  • 举报
回复
这就是协议,事先应当先发送一特定字符串标明接下来发送的是文件。
n27741 2007-02-25
  • 打赏
  • 举报
回复
我做过一个文件传输的功能;
其中为了保证数据块一定被服务器接收并写入文件
我当时让服务器发送一个回执 告诉客户端此块已经完成 可以发送下一个包了
这个时候客户端就用了ReadBuffer(void *p ,unsige size);
当时我也有楼主这样的疑惑,不知道这个函数应该在那里调用
索性就写在循环里面了;
结果我调试的就发现了
调用ReadBuffer(void *p ,unsige size);的时候
这个循环被阻塞了!
应该说 是这个侦听的线程被堵塞了!
直到服务器有反馈消息来临
线程才放行,就是这样..
不知道LZ清楚我的意思没有

阿发伯 2007-02-21
  • 打赏
  • 举报
回复

void __fastcall TMainForm::ClientConnect(AnsiString Host)
{
TCPClient->Host = Host;
try
{
TCPClient->Connect();
ClientThread = new TClientThread(); //idTCPClient链接后建立线程
ClientSend(ctConnect);
}
catch(Exception *E)
{
MessageDlg("链接错误:\n" + E->Message, mtError, TMsgDlgButtons() << mbOK, 0);
}
}

void __fastcall TMainForm::ClientDisconnect(void)
{
ClientThread->Terminate(); //idTCPClient断开链接前挂起线程
TCPClient->Disconnect();
}
阿发伯 2007-02-21
  • 打赏
  • 举报
回复
给个例子片断供参考:

enum TCommType{ctConnect, ctDisconnect, ctBegin, ctPos, ctEnd, ctInfo, ctChat};

struct TCommBlock
{
TCommType Type;
char GameName[31];
int Param1;
int Param2;
char Msg[101];
};
//---------------------------------------------------------------------------
class TClientThread : public TThread
{
private:
TCommBlock CB;
void __fastcall HandleInput(void);
protected:
virtual void __fastcall Execute(void);
public:
__fastcall TClientThread(void);

};



TMainForm *MainForm;
TClientThread *ClientThread = NULL;
//---------------------------------------------------------------------------
__fastcall TClientThread::TClientThread(void) : TThread(true)
{
FreeOnTerminate = true;
Resume();
}

void __fastcall TClientThread::HandleInput(void)
{
AnsiString s = CB.GameName;
switch (CB.Type)
{
case ctConnect:
MainForm->Connected = CB.Param1 == 1;
if (CB.Param1 == 1)
{

MainForm->InfoLog->Lines->Add(s + "加入游戏");
}
else
{
MainForm->ClientDisconnect();
MainForm->InfoLog->Lines->Add("对不起游戏人数已满");
}
break;
case ctDisconnect:
if (s == MainForm->GameName)
{
MainForm->ClientDisconnect();
MainForm->Connected = false;
}
MainForm->InfoLog->Lines->Add(s + "退出游戏");
break;

case ctChat:
MainForm->InfoLog->Lines->Add(s + ": " + AnsiString(CB.Msg));
break;
default:
break;

}
}

void __fastcall TClientThread::Execute(void)
{
while (!Terminated)
{
if (!MainForm->TCPClient->Connected())
Terminate();
else
{
try
{
MainForm->TCPClient->ReadBuffer(&CB, sizeof(CB));
Synchronize(&HandleInput);
}
catch(...){}
}

}
}
sbkopoky 2007-02-17
  • 打赏
  • 举报
回复
有一个香港和悦网络电话的源文件 ,有兴趣妨进入我的BLOG看看
pencilend 2006-12-05
  • 打赏
  • 举报
回复
你可以用ReadFromStack来判断是否有数据。。。有数据后,再用ReadBuffer取数据,
看帮助,其实上,ReadBuffer也是先调用ReadFromStack来判断是否有数据。。。


以下是ReadFromStack的帮助
Reads data from the protocol stack using the socket binding.

function ReadFromStack(const ARaiseExceptionIfDisconnected: Boolean; ATimeout: Integer; const ARaiseExceptionOnTimeout: Boolean): Integer; virtual;

Parameters

const ARaiseExceptionIfDisconnected: Boolean = True

Raise an Exception when disconnected. Default value is True.

ATimeout: Integer = IdTimeoutDefault

Timeout value to wait for a readble socket handle. Default value is IdTimeoutDefault.

const ARaiseExceptionOnTimeout: Boolean = True

Raise an exception when a timeout occurs. Default value is True.

Returns

Integer - Number of bytes read from the protocol stack.

Description

ReadFromStack is an Integer function used to read data from the IP protocol stack for the peer connection into the Indy buffer maintained for the connection.

ATimeout indicates the number of milliseconds to wait for the IOHandler to become readable prior to reading data. When ATimeout contains the value IdTimeoutDefault, ReadTimeout will be used as the timeout value when it is non-zero. Otherwise, IdTimeoutInfinite is used as the timeout value. If a timeout occurs, an EIdReadTimeout exception will be raised when ARaiseExceptionOnTimeout is True. Otherwise ReadFromStack performs no additional processing, and uses -1 as the return value for the method.

ReadFromStack calls CheckForDisconnect using the value specifed in ARaiseExceptionIfDisconnected to determine if an exception is raised when the connection is closed. If the socket is not Connected, ReadFromStack will exit from the method.

ReadFromStack uses IOHandler to determine when the connection is readable, and to receive data from the input source. ReadFromStack updates ClosedGracefully indicating when all data has been read from the stack prior to closing the connection, and calls TIdStack.CheckForSocketError to determine if the connection closed abnormally.

When ClosedGracefully is False, the protocol stack is used to check for an Id_WSAESHUTDOWN error and allows the socket to disconnect when the error is detected. If the Indy read buffer contains no unread data, the Id_WSAESHUTDOWN exception is re-raised using the protocol stack handler.

ReadFromStack provides support for TIdConnectionIntercept by calling the Receive handler for the Intercept when Enabled. ReadFromStack also performs 8-bit to 7-bit character translations when ASCIIFilter is True.

Finally, ReadFromStack moves data read from the input source to the internal Indy buffer, and sets the return value to the number of bytes handled by the operation.

ReadFromStack can be a time intensive operation due to network contention and the nature of blocking sockets. ReadFromStack should be the only location where data is read from the protocol stack.
sczyq 2006-11-17
  • 打赏
  • 举报
回复
只有使用线程来检测。

idTCPClient 一般是主动地向idTCPServer发放数据,然后接收idTCPServer发送过来的数据,直到接收到“结束”的标志,这样就不必使用线程了。
free1688 2006-11-17
  • 打赏
  • 举报
回复
沙发,支持,飘过。
xinxin_2006 2006-11-17
  • 打赏
  • 举报
回复
使用线程来检测,那么线程又何时触发呢?这又回到没解决上了啊!
线程是肯定要触发才能执行的啊,那么线程触发的标志是检测到
IDTCPclient收到数据了.可是问题还在--线程怎么知道IDTCPclient
有数据要接受?线程又何时触发呢?
总不能用一个定时器,过段时间就启动一次(这样就会出现数据不同步现象,也不好啊)!!
恳请高手门帮忙解答下这个问题!!!!

1,317

社区成员

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

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