CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C++ Builder >  基础类

一个关于线程的小问题(10000分都行)

楼主jim2001999(乐天)2005-06-01 20:42:19 在 C++ Builder / 基础类 提问

示意图如下:    
      我在客户端生成一个线程Thread连接到服务器和服务器交换数据。我在主程序的一个函数中向服务器发送了一个请求,函数这个时候Sleep,等待运行结果,服务器端处理后返回数据到客户端,由线程接收到数据,写入到缓冲区。函数这时取缓冲区数据。但是程序运行不成功。  
        我设置断点执行后发现,实际上运行的过程是客户端等待主进程的函数执行完成后,才执行的线程接收代码。不知道为什么,这种问题不知道怎么解决。请各位帮帮忙。不胜感激!  
   
  像这样的:  
  客户端                                                       服务器  
      |--Thread----------------------Thread  
      |--Function----------------------|  
  问题点数:100、回复次数:14Top

1 楼leonatcs(LeonKennedy)(时常逛一逛csdn,有益身心健康。)回复于 2005-06-01 22:23:50 得分 5

那只能是你没有在合适的时候启动线程了。Top

2 楼xpdavis(咕嘟-不想孤独)回复于 2005-06-01 22:53:40 得分 5

最好还是给出代码好找出错误Top

3 楼jemyzhang(妙狐)回复于 2005-06-02 00:27:09 得分 5

可以在主进程中进入循环,判断数据是否收到,如果收到再退出循环。  
  不知可否解决问题Top

4 楼chiengod(钱神爷)回复于 2005-06-02 08:28:11 得分 5

那就不要用Sleep了,发送请求后启动线程,不断的判断、读缓冲区。Top

5 楼constantine(飘遥的安吉儿)回复于 2005-06-02 08:46:27 得分 5

看代码吧,还有不是说主线程执行后才执行什么的....  
  如果这样还叫多线程..Top

6 楼songhtao(三十年孤独)回复于 2005-06-02 08:57:26 得分 5

主要还是要看代码,给你个例子参考:http://www.pcbookcn.com/article/2333.htm  
  Top

7 楼jim2001999(乐天)回复于 2005-06-02 09:23:47 得分 0

谢谢楼上的高手。简化的错误关键代码如下:  
        我先通过点Button1连接到服务器。然后线程一直监视数据到来。然后点Button4,服务器处理后返回"bb",但始终是打印的是There   error,运行顺序是先把Button4Click运行完毕后,再运行的ClientThread的ReadStr(buf)。请各位高手帮忙!!!谢谢。  
   
  ClientThread.cpp  
   
  //---------------------------------------------------------------------------  
  //   客户收受线程  
  #include   <vcl.h>  
  #pragma   hdrstop  
  #include   "ClientUnit1.h"  
  #include   "ClientThread.h"  
  #pragma   package(smart_init)  
  //---------------------------------------------------------------------------  
  __fastcall   TClientThread::TClientThread(bool   CreateSuspended,  
                        TClientWinSocket   *   ASocket):TThread(CreateSuspended)  
  {  
                FreeOnTerminate=true;                       //   线程中止后释放线程  
                ClientSocket=ASocket;  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TClientThread::Execute()  
  {  
                char   buf[1024+1];  
                pStream=new   TWinSocketStream(ClientSocket,0x7fffffff);  
                while(!Terminated   &&   ClientSocket->Connected)  
                      if     (ReadStr(buf)>0)  
                            {  
                                    Message=buf;  
                                    Synchronize(MemoAdd);  
                                    strcpy(Form1->array,buf);  
                            }  
                      else  
                            ClientSocket->Close();           //   返回的串长为0表示已断开  
                delete   pStream;  
   
                Message="已与服务器断开连接...";  
                Synchronize(MemoAdd);  
  }  
  //---------------------------------------------------------------------------  
  int     __fastcall   TClientThread::ReadStr(char   *   buf)     //接收数据  
  {  
                int   Len=0;  
                pStream->WaitForData(0x7fffffff);           //   等待到有串或断开  
                if   (pStream->WaitForData(10000))             //   第二次为假表示断开  
                        Len=pStream->Read(buf,1024);  
                                //   ClientSocket关闭后,pStream->Read()会产生异常,所以要判定或try  
                buf[Len]=0;  
   
                return   Len;  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TClientThread::MemoAdd()   //将数据加入Memo1中  
  {  
                Form1->Memo1->Lines->Add(Message);       //   Synchronize(MemoAdd);  
  }  
  //---------------------------------------------------------------------------  
   
  ClientUnit1.cpp  
   
  /*  
          BCB-Socket阻塞模式通讯测试-客户端  
  */  
  //---------------------------------------------------------------------------  
  #include   <vcl.h>  
  #pragma   hdrstop  
  #include   "ClientThread.h"  
  #include   "ClientUnit1.h"  
  //---------------------------------------------------------------------------  
  #pragma   package(smart_init)  
  #pragma   resource   "*.dfm"  
  TForm1   *Form1;  
  //---------------------------------------------------------------------------  
  __fastcall   TForm1::TForm1(TComponent*   Owner)  
                  :   TForm(Owner)  
  {  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TForm1::Button1Click(TObject   *Sender)  
  {  
                String   IP=Edit1->Text.Trim();  
                if   (IP!="")  
                      if   (!ClientSocket1->Active)  
                          {  
                                ClientSocket1->Address=IP;  
                                ClientSocket1->Port=Edit3->Text.ToInt();  
                                try  
                                    {  
                                          ClientSocket1->Open();  
                                          Memo1->Lines->Add("已连接到:"+  
                                                                              IP+":"+ClientSocket1->Port);  
                                          Memo1->Lines->Add("本机IP:"+  
                                                                ClientSocket1->Socket->LocalAddress+  
                                                                ":"+ClientSocket1->Socket->LocalPort);  
   
                                          TClientThread   *thread=  
                                                  new     TClientThread(false,ClientSocket1->Socket);  
                                    }  
                                catch(...)  
                                    {  
                                          Memo1->Lines->Add("连接失败");  
                                    }  
                        }  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TForm1::Button2Click(TObject   *Sender)  
  {  
                ClientSocket1->Socket->SendText(Edit2->Text);  
                Edit2->Text="";  
  }  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TForm1::Button3Click(TObject   *Sender)  
  {  
                ClientSocket1->Close();  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TForm1::FormClose(TObject   *Sender,   TCloseAction   &Action)  
  {  
                ClientSocket1->Close();  
  }  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TForm1::ClientSocket1Error(TObject   *Sender,  
                TCustomWinSocket   *Socket,   TErrorEvent   ErrorEvent,   int   &ErrorCode)  
  {  
                ErrorCode=0;  
  }  
  //---------------------------------------------------------------------------  
   
   
  void   __fastcall   TForm1::Button4Click(TObject   *Sender)  
  {  
                  this->ClientSocket1->Socket->SendText("aa");  
   
                  ::Sleep(1000);  
   
                  if(String(array)   ==   "bb")  
                  {  
                                  this->Memo1->Lines->Add("there   ok!!!!");  
                  }  
                  else  
                  {  
                                  this->Memo1->Lines->Add("there   error!!!!");  
                  }  
  }  
  //---------------------------------------------------------------------------  
  Top

8 楼lidawen(Darwin)回复于 2005-06-02 09:41:16 得分 3

upTop

9 楼jim2001999(乐天)回复于 2005-06-02 11:43:13 得分 0

顶下。。。  
  各位高手。帮忙啊。我的毕业设计的大问题就靠你们了。。!!!!!不胜感激啊!Top

10 楼jim2001999(乐天)回复于 2005-06-02 21:02:50 得分 0

顶啊!!!Top

11 楼xpdavis(咕嘟-不想孤独)回复于 2005-06-02 23:04:38 得分 60

程序没问题,不过设计的不好,回头给你一个好点的设计Top

12 楼xpdavis(咕嘟-不想孤独)回复于 2005-06-03 08:39:21 得分 0

简单的说,这个设计最大的缺陷在于主线程必须等待一个固定的时间(可能很长),以确定数据已经接收到。这样的设计反应太迟钝了,其实只要在SOCKET线程收到数据时发送消息(COPY   DATA消息)给主线程,主线程只要做好消息映射就可以了,这样就可以驱动TForm1的一个方法将收到的数据显示出来。  
  另外,楼主的设计有点混乱,2个单元文件互相包含,一般而言这种做法是不可取的。Top

13 楼flyback(墨羽)回复于 2005-06-03 08:46:48 得分 7

一开始就应该启动线程,但是必须让它等待一个主程序的完成标志  
  global   boolean   g_bIsOk  
  main()  
  {  
  createthread   (abc)  
  abc.run  
  ...  
  ...  
  g_bIsOk   =   true  
   
  }  
  abc()  
  {  
  if(g_bIsOk   ==   true)  
  {  
  ...  
  }  
  else  
  {  
  sleep(...)  
  }  
  }Top

14 楼jim2001999(乐天)回复于 2005-06-03 09:36:36 得分 0

to:xpdavis(咕嘟),你好。我的邮箱是:jim2001999@163.com     发点代码谢谢了。Top

相关问题

  • 通讯线程小问题
  • 多线程的小问题
  • 线程里的一个小问题。
  • 线程编程的一个小问题
  • 关于线程的小问题
  • 关于线程的一个小问题
  • 一个线程的小问题
  • 创建线程的小问题
  • 线程的通信小问题?
  • 关于线程的的小问题!

关键词

  • 线程
  • 服务器
  • 函数
  • 数据
  • 代码
  • 执行
  • 客户
  • 连接
  • 消息
  • clientsocket

得分解答快速导航

  • 帖主:jim2001999
  • leonatcs
  • xpdavis
  • jemyzhang
  • chiengod
  • constantine
  • songhtao
  • lidawen
  • xpdavis
  • flyback

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo