网络通讯与线程高手请进.

mjxllj 2006-07-24 06:27:02
写了一个TCP的通讯程序,主要功能是监听客户端的请求处理后然后发往下一方,用的是TServerSocket控件,监听到客户端的连接请求后就生成一个线程实例,用的都是VCL封装好了方法与事件,可是现在出现的问题是运行一段时间后程序自动退出了,也没有报错.愁死我了.
操作系统是win2000 server,我用了很多try{},为的是保证不会出现对话框,但会把错误信息写进日志.线程中操作了一个VCL控件,叫TListView, 用来显示通讯结果的.程序退出时什么提示也没有,日志也没记录,大侠们给我指条明路吧..........
...全文
339 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
13661023811 2006-08-01
  • 打赏
  • 举报
回复
多线程的优点就是要各个独立处理,如果你在线程中需要将处理的进度、结果反馈到listview中,个人觉得给它发消息,而不要等待消息的返回,也就是线程不等待,继续执行。
TurtleRock 2006-07-31
  • 打赏
  • 举报
回复
多线程同时访问ListView可能会导致错误,必须使用线程同步来解决,但线程同步必然导致通信速度的下降。
楼主看看我的帖子,共同讨论一下

http://community.csdn.net/Expert/TopicView1.asp?id=4910019
TurtleRock 2006-07-31
  • 打赏
  • 举报
回复
多线程同时访问ListView可能会导致错误,必须使用线程同步来解决,但线程同步必然导致通信速度的下降。
楼主看看我的帖子,共同讨论一下
mjxllj 2006-07-26
  • 打赏
  • 举报
回复
最大的问题是平时运行很正常,生产环境没法模拟,以下是主要代码.

void __fastcall TMainForm::AtmServerGetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread)
{
try {
Memo->Lines->Add("A new Connect ... ");
SocketThread = new TMyServerThread(false,ClientSocket);
}
catch (...) {
vWriteATMLog(1," Create Server Thread Error.\n");
}
}


void __fastcall TMyServerThread::ClientExecute()
{
char buffer[2048];
int RcvLen = 0, SndLen = 0;

TWinSocketStream *pStream=NULL;
MainForm->vWriteATMLog(1,"PID=["+PID+"]ClientExecute Begin!\n");

Sleep(100);
memset(buffer,0x00,sizeof(buffer));
memset(&iso_atmrsp,0,sizeof(iso_atmrsp));
memset(&iso_atm,0,sizeof(iso_atm));
memset(&TranView,0x00,sizeof(TranView));
memset(TranView.NOTE,0x00,sizeof(TranView.NOTE));

if(!ClientSocket->Connected) return;
while(true)
{
try {
pStream = new TWinSocketStream(ClientSocket, 30000);
memset(buffer, 0x00, sizeof(buffer));
if (pStream->WaitForData(10000))
{// give the client 10 seconds to start writing

RcvLen = pStream->Read(buffer, sizeof(buffer));
if ( RcvLen == 0 || RcvLen<9)
{
MainForm->vWriteErrLog("PID=["+PID+"]Read Error or Nothing.\n");
break;
}

MainForm->vWriteATMLog(1,"PID=["+PID+"]===================================================================================\n");

String sLine,sTmp;
String sTmp2;
for(int ii=1;ii<=RcvLen;ii++)
{
sTmp2="";
for(int jj=1;jj<=8;jj++)
{
if((buffer[ii-1]>>(jj-1))&(0x01)==1) sTmp2="1"+sTmp2;
else sTmp2="0"+sTmp2;

}
sLine=sLine+StrToC16(sTmp2.SubString(1,4))+StrToC16(sTmp2.SubString(5,4))+" ";
}
sTmp=" Receive From ATM :"+sLine+"|\n";
MainForm->vWriteATMLog(1,"PID=["+PID+"]"+sTmp);

memcpy(buffer,buffer+8,RcvLen-8);
RcvLen=RcvLen-8;

//收到请求,数据 buffer
//解包 按类型解 解后内容放入 结构中

if ( UnPackATMMsg(buffer,RcvLen) < 0 )
{
MainForm->vWriteErrLog("PID=["+PID+"] 解包文出错!\n ");
break;
}

MainForm->GetAtmIndex( m_cAtmNo, m_AtmSn, AtmIP, AtmPort ,PINKEY,PINMK,MACKEY,MACMK,PERNO,NETNO);
if ( m_AtmSn < 0 )
{
MainForm->vWriteErrLog("PID=["+PID+"]Get ATM Index Error : ["+(String)(char *)m_cAtmNo+"]\n");
break;
}

if ( ProcAtmMsg( m_cAtmNo, pStream , ClientSocket ) < 0 )
{
MainForm->vWriteErrLog("PID=["+PID+"]ProcAtmMsg Error : ["+(String)(char *)m_cAtmNo+"]\n");
break;
}

}
} // end try
catch (Exception &E) {
AnsiString str;
str = E.Message;
MainForm->vWriteErrLog("PID=["+PID+"]SerThread : ["+str+"]\n");
}
break;
}//while

delete pStream;
ClientSocket->Close();
MainForm->vWriteATMLog(1,"PID=["+PID+"]ClientExecute End!\n");
}
Andrionda 2006-07-25
  • 打赏
  • 举报
回复
楼主还是贴出来相关代码
iec 2006-07-25
  • 打赏
  • 举报
回复
很笼统,把代码贴出来吧
疯狂的技术宅 2006-07-25
  • 打赏
  • 举报
回复
如果在线程中出现异常而又没有处理的话可能会出现你描述的情况。
sfengnet 2006-07-25
  • 打赏
  • 举报
回复
单步跟踪一下,如果线程要通知主线程响应显示某些内容时,应该使用互斥或者是临界区之类的
僵哥 2006-07-25
  • 打赏
  • 举报
回复
使用多线程也使用VCL则要注册使用临界区来进行访问的同步.尽可能保证访问时指针的安全性.甚至楼主使用了TListView那么就更需要注册线程安全,再则这种设计本来就有合理性争议,使用多线程为的就是提高速,却同时访问一个ListView,那么是不是自己给事给绑根绳子?
过客猫2022 2006-07-25
  • 打赏
  • 举报
回复
你在BCB下运行它,可能抛出的异常被你的try处理了,在BCB下可以会捕获所有异常

1,317

社区成员

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

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