帮忙看看这个线程有什么问题?读服务端内容!

zahlink 2003-08-26 09:59:49
TMOThread = class(TThread)
private
ls_fillStr :string;
protected
Procedure FillEdit;
procedure Execute; override;
end;
procedure TMOThread.FillEdit;
begin
form1.MemoMo.Lines.Add(ls_fillStr);
end;
procedure TMOThread.Execute;
var
theStream :TWinSocketStream;
head:VAPP_Head;
bindresp:VAPP_Bind_Resp;
deliver:VApp_Deliver;
begin
while form1.ClientMo.Active do
try
TheStream :=TWinSocketStream.Create(form1.ClientMo.Socket,5000);
try
begin
fillchar(head,sizeof(VAPP_Head),0);
thestream.Readbuffer(head,sizeof(VAPP_Head));
head.len:=ntohl(head.len);
head.CommandId:=ntohl(head.CommandId);
head.seqno:=ntohl(head.seqno);
ls_fillStr:=inttostr(head.len);
synchronize(FillEdit);
ls_fillStr:=inttostr(head.CommandId);
synchronize(FillEdit);
ls_fillStr:=inttostr(head.seqno);
synchronize(FillEdit);
case head.CommandId of
APP_BIND_RESP:
begin
fillchar(bindresp,sizeof(VAPP_Bind_Resp),0);
thestream.Read(bindresp,sizeof(VAPP_Bind_Resp));
ls_fillStr:='接收到bindresp!';
synchronize(FillEdit);
ls_fillStr:=inttostr(bindresp.status);
synchronize(FillEdit);
begin
if bindresp.status=0 then
begin
ls_fillStr:='bindresp返回正常!';
molasttime:=now();
synchronize(FillEdit);
end
else
begin
ls_fillStr:='bindresp返回错误!';
synchronize(FillEdit);
end;
end;
end;
APP_UNBIND_RESP:
begin
ls_fillStr:='unbind_resp成功!';
synchronize(FillEdit);
end;
APP_ACTIVE_RESP:
begin
ls_fillStr:='active_resp成功!';
synchronize(FillEdit);
end;
else
begin
ls_fillStr:='收到其它包,命令: ' + inttostr(head.CommandId);
synchronize(FillEdit);
end;
end;
end;
finally
end;
finally
theStream.Free;
end;

end;
**********************
运行后在clientsocketconnect事件中tmothread.create(false);
问题是读取一个下发信息之后,其它的回复信息没有不知道是什么原因!
客户端是阻塞连接,服务端是线程服务器!
...全文
31 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
爱编程的老五 2003-08-27
  • 打赏
  • 举报
回复
其实客户端接受数据,一般来说是可以不用线程的,但你如果一定要用线程,你可以将TClientSocket作为线程的一个属性来用,然后所有的处理均在线程中完成,比如发送数据,接受数据.
爱编程的老五 2003-08-27
  • 打赏
  • 举报
回复
你所说的客户端我想只是相对于应用而言,对于socket并不是客户端.你如果只是被动的接受数据,那么应该用TServerSocket而不是TClientSocket.
据我了解,如果你要接受数据的话,除了TServerSocket是等待数据的外,TClientSocket是主动发起的,因此应该是TClientSocket发送命令(也即数据),然后接受TServerSocket返回的数据,如此反复,才能形成一个环路.如果你需要的数据很大,可能一次处理不完,你还要发送多次的处理命令来交互.
你所说的这个线程是一直在执行的,但依我看来,它应该是在你完成一次数据接受之后便结束了的,而不是如你所说的一直在执行,还有你写在Connect事件中创建这个线程,时机是否不太恰当,而应该是你用TClientSocket发送了一个数据之后才创建呢?
zahlink 2003-08-27
  • 打赏
  • 举报
回复
如果不这样做,有什么好建议也可以啊!想不出来了
zahlink 2003-08-27
  • 打赏
  • 举报
回复
是接收到head之后判断id 是什么,然后按照id继续接受其他的内容!
zahlink 2003-08-27
  • 打赏
  • 举报
回复
这个就是个客户端接收数据的线程啊,不包含发送!它自己不会结束,一直在阻塞读取服务端过来的内容!如果我要用socket发送时就会出错,因为线程没停过!socket占用,我如果连上了之后一直读取服务端内容就不会错,但是我向服务端提交数据就出错!
lxpbuaa 2003-08-27
  • 打赏
  • 举报
回复
首先,while form1.ClientMo.Active do
try
TheStream :=TWinSocketStream.Create(form1.ClientMo.Socket,5000);
应该是不对的吧!怎么会循环建立读写流呢?
应该这样:
TheStream :=TWinSocketStream.Create(form1.ClientMo.Socket,5000);
while form1.ClientMo.Active do
try
……

————————————————————————————————————
宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
————————————————————————————————————
outer2000 2003-08-27
  • 打赏
  • 举报
回复
你怎么发的?thestream.Readb=uffer(head,sizeof(VAPP_Head));这句可是发就错了;
爱编程的老五 2003-08-27
  • 打赏
  • 举报
回复
你的线程写的不就是接受完一个信息之后就结束了吗?
我都没有搞懂,你到底要干什么?如果你是主动向服务器端发起命令请求的话,你怎么会用线程呢?服务器端应该用线程才正确吧.
另外你的代码也有问题,你在处理接受到的信息时应该是包含在一个循环中的呀,否则顺序处理了之后不就结束了??
zahlink 2003-08-27
  • 打赏
  • 举报
回复
menliwxj(有缘):我是按照有一个例子做的http://expert.csdn.net/Expert/topic/1354/1354558.xml?temp=.3853266,基本上是和那个帖子的要求一致!你说的‘可以将TClientSocket作为线程的一个属性来用,然后所有的处理均在线程中完成,比如发送数据,接受数据.’怎么做呢,请赐教!
zahlink 2003-08-27
  • 打赏
  • 举报
回复
因为我要首先发起连接到服务端,所以我就要用cliensocket控件啊!但是在连接之后要发送一些数据,不是说只发送一次就可以,要很多次交互才行!有的时候是只要我这边有数据就要向服务端发送,然后接受TServerSocket返回的数据,有的时候是服务端有数据就要回发到我这里,然后我在发送回复!所以要一直读取才行!
IORILI 2003-08-26
  • 打赏
  • 举报
回复
学习 帮你UP
zahlink 2003-08-26
  • 打赏
  • 举报
回复
刚运行的时候是好的,当我发信息给服务端的时候,线程负责接收回复包,但是现在接收不到回复内容了,好象断掉了,是我调用的问题,还是我的线程有问题呢!帮忙啊
zahlink 2003-08-26
  • 打赏
  • 举报
回复
哎,还是谢谢吧!谁知道啊!
上海老李 2003-08-26
  • 打赏
  • 举报
回复
没用DELPHI做过网络方面,呵呵,帮你UP吧

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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