Sockets问题,高手都来看啊~(解决问题的人分全给他!)

Blueion 2005-04-21 09:18:34
我的服务器端通过TServerSocket控件接受客户端TClientSocket传来的数据,两个控件都处在ctNonBlocking状态。服务器接收数据后,对数据解析后写入数据库,最后使用SendText方法向客户端发送一条确认信息。每当有数据传入后,就生成一个线程来进行数据库操作,最后在线程中向客户端发送一条确认信息。
我的问题是当我还未发出确认信息前,此客户端或别的客户端发来数据,那么SendText的时候就会出现异常,使得发送确认信息不成功。这是为什么啊?我在本机上联10个客户端最后每个客户端总有发出去收不到确认信息的数据。我都郁闷死了,请大家帮忙啊……
...全文
354 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
Blueion 2005-05-10
  • 打赏
  • 举报
回复
结帐 谢谢大家的关心
Blueion 2005-05-10
  • 打赏
  • 举报
回复
找到原因拉!原来不是SendText的问题,是当执行info=Socket->ReceiveText(),如果客户端的发送比较急,info得到的字符串是前后两条连在一起的。因为末尾没有加“,”,所以用“,”作分隔符最后一位会出错。
就是没想到它的出错光标指SendText那里……
titan_ysl 2005-05-10
  • 打赏
  • 举报
回复
void __fastcall TDataModule1::ServerSocket1ClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{

TRealInfoThread *RealInfoThread=new TRealInfoThread(false);

这里有问题:
如果ServerSocket1ClientRead事件 在TRealInfoThread::Execute()执行的时候发生了n次,就会有n个同名RealInfoThread对象产生。这样会有不可预料的结果。
jinhaiwu 2005-05-09
  • 打赏
  • 举报
回复
一个线程跟一个ADOConnection的话,用ADO操作是没有问题的。
发送的话最好拿到主线程中发送,可以在线程中用Synchronize(发送函数)
WiseNeuro 2005-04-30
  • 打赏
  • 举报
回复
关注一下
qin_wei 2005-04-29
  • 打赏
  • 举报
回复
看问题好像不是socket的事,而是你的两个线程同时操作DataModule1->ADOQuery_update了,所以catch不到。
用什么方法互斥一下应该就可以了。
Blueion 2005-04-29
  • 打赏
  • 举报
回复
不是吧,ADO控件不是线程安全的吗?
qin_wei 2005-04-28
  • 打赏
  • 举报
回复
你用的什么数据库?不太清楚你的问题出在哪,把CoInitialize(NULL);去掉放到主窗口里试验一下
TRealInfoThread *RealInfoThread=new TRealInfoThread(false);
这句有漏洞,new出来后的线程在execute后是执行完毕了,但内存镜象没被释放,记得要delete
我不懂电脑 2005-04-28
  • 打赏
  • 举报
回复
非阻塞方式很好的,关键是要细心调试,另外你用非阻塞方式就没必要用线程了,用阻塞方式的话TServerSocket会自动创建线程的,并具有线程池机制。
Blueion 2005-04-28
  • 打赏
  • 举报
回复
我用的是SQL Server2000,异常是"在异步运行时,操作不能被执行"
To:songhtao(三十年孤独) 如果我不用线程的话,把线程里的语句写到ClientRead里,在同样的情况下程序会报异常.说什么Incorrect synatax near"s",出错光标指向SendText那句.
To:qin_wei(烤毛蛋) CoInitialize(NULL);必须要有,不然程序直接报错.因为线程里有了FreeOnTerminate=true;所以内存已经释放了.
Blueion 2005-04-25
  • 打赏
  • 举报
回复
高手呢?斑竹呢? 我提的问题怎么没人给个答案?非阻塞方式就这么烂吗?
Blueion 2005-04-22
  • 打赏
  • 举报
回复
不能在我原来的代码上修改一下了吗 重写不爽的了
constantine 2005-04-22
  • 打赏
  • 举报
回复
兄弟,你用的是非阻塞方式,异常是不能通过try来捕捉的,
阻塞才可以用try捕捉
非阻塞要在OnError里面捕捉
你要消息回复确定的就用阻塞
很好用的,用indy控件就可以,都是阻塞的
等待多久自己设置,有timeout
不会慢的
Blueion 2005-04-22
  • 打赏
  • 举报
回复
阻塞方式好使吗?我不知道阻塞等待客户端写需要多长时间啊
我不懂电脑 2005-04-22
  • 打赏
  • 举报
回复
既然使用多线程的话,那就用阻塞方式吧。
NetSpider9804040 2005-04-22
  • 打赏
  • 举报
回复
帮楼主顶一下
Blueion 2005-04-21
  • 打赏
  • 举报
回复
贴点代码吧(因为在dll里使用的是DataModule):

.h文件:

//---------------------------------------------------------------------------


class TDataModule1 : public TDataModule
{
__published: // IDE-managed Components
TServerSocket *ServerSocket1;
TADOConnection *ADOCon_Server;
TADOQuery *ADOQuery_update;
TServerSocket *ServerSocket2;


void __fastcall ServerSocket1ClientRead(TObject *Sender,
TCustomWinSocket *Socket);
void __fastcall ServerSocket1ClientError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent,
int &ErrorCode);
void __fastcall ServerSocket2ClientError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent,
int &ErrorCode);
void __fastcall ServerSocket2ClientRead(TObject *Sender,
TCustomWinSocket *Socket);
private: // User declarations
public: // User declarations
__fastcall TDataModule1(TComponent* Owner);
};
//---------------------------------------------------------------------------

class TRealInfoThread : public TThread
{
private:

protected:
void __fastcall Execute();
public:
__fastcall TRealInfoThread(bool CreateSuspended);
TCustomWinSocket *SocketShare;
AnsiString ID,empty_num,vehicle_num,link_status;
};
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------



.cpp文件:

//---------------------------------------------------------------------------

void __fastcall TDataModule1::ServerSocket1ClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString info;
AnsiString updatesql;
TStringList *StrList= new TStringList();

info=Socket->ReceiveText(); //从sockets中读取数据

StrList->Delimiter=','; //分析数据
StrList->DelimitedText = info;
if(StrList->Strings[0]=='s'||StrList->Strings[0]=='S') //实时信息
{
TRealInfoThread *RealInfoThread=new TRealInfoThread(false);
RealInfoThread->ID=Trim(StrList->Strings[1]);
RealInfoThread->empty_num=Trim(StrList->Strings[2]);
RealInfoThread->vehicle_num=Trim(StrList->Strings[3]);
RealInfoThread->link_status=Trim(StrList->Strings[4]);
delete StrList;
// 添加到实时信息库

RealInfoThread->SocketShare=Socket;
RealInfoThread->Resume();
}


}
//-----------------------------------------------------------------------



void __fastcall TDataModule1::ServerSocket1ClientError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
ErrorCode = 0;
Socket->SendText("0");
ServerSocket1->Active=false;
ServerSocket2->Active=true;

}
//---------------------------------------------------------------------------




//---------------------------------------------------------------------------


void __fastcall TRealInfoThread::Execute()
{

AnsiString updatesql="update realtime_info set empty_num="+empty_num+",vehicle_num="+vehicle_num+",link_condition="+link_status+" where p_id="+ID+"";

CoInitialize(NULL);
DataModule1->ADOQuery_update->Close();
DataModule1->ADOQuery_update->SQL->Clear();
DataModule1->ADOQuery_update->SQL->Add(updatesql);
DataModule1->ADOQuery_update->ExecSQL(); //到这里没有问题
try
{
SocketShare->SendText("1"); //就这里出现异常,下面的catch也抓不到这个异常
}
catch(...)
{
SocketShare->SendText("0");
}
}


//---------------------------------------------------------------------------



__fastcall TRealInfoThread::TRealInfoThread(bool CreateSuspended)
: TThread(CreateSuspended)
{

FreeOnTerminate=true;
}

---------------------------------------------------------------------------

1,317

社区成员

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

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