关于TClientSocket多线程使用时,需要加锁吗?
请在在主线程中有个TClientSocket,使用的是非阻塞模式工作。在ClientSocketRead事件中,获得服务器发来的数据,
解析并保存在队列中。另外一个线程处理队列中的数据。处理完后,需要用Socket->SendBuf方法发送(写)数据到服务端。
请问各位,在这两个线程中主线程读(接收),另外子写(发送)。这样操作,需不需要加个 临界区之类的锁。把Socket操作
时,要分别锁起来? 谢谢。
官方文档里有句话:
Use a non-blocking socket when the socket needs to synchronize reading and writing with server sockets.
不知道如何正确理解?
[解决办法]
非阻塞情况下这个必须要枷锁,因为你接受线程和发送线程是对同一个队列里的数据进行处理,存在资源竞争,需要枷锁进行保护,防止队列中的数据被改写
[解决办法]
void __fastcall TServerFrm::ServerSocket1GetThread(TObject *Sender,这里产生客户端处理线程。
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread)
{
SocketThread=new MyServer(false,ClientSocket,600000);
}
void __fastcall MyServer::Connected()客户端的处理相似,代码太长发不完了,你留个邮箱,我把这个例子发给你,你看看。这个是一个网友写的例子,用来学习还是很好的。
{
ActiveNum++;
RemoteHostIP=ClientSocket->RemoteAddress;
RemoteHostProt=ClientSocket->RemotePort;
Message="客户机:"+RemoteHostIP+":"+RemoteHostProt+" 已连接...";
Synchronize((TThreadMethod)&AddMessage);
ServerFrm->Label1->Caption="当前连接数:"+IntToStr(ActiveNum);
}
//---------------------------------------
void __fastcall MyServer::DisConnected()
{
ActiveNum--;
ServerFrm->Label1->Caption="当前连接数:"+IntToStr(ActiveNum);
Message="客户机:"+RemoteHostIP+":"+RemoteHostProt+" 断开连接...";
Synchronize((TThreadMethod)&AddMessage);
}
//---------------------------------------
void __fastcall MyServer::DataDisposal(void) //所有数据处理
{
char GetStr;
String RevStr;
char buf[1024+1];
try{
while(ClientSocket->Connected==true)
{
memset(buf,0,sizeof(buf));
if(ReceiveStr(buf,1024)>0)
{
RevStr=String(buf);
Message=RemoteHostIP+"::"+RevStr;
Synchronize((TThreadMethod)&AddMessage);
TransmitStr=RemoteHostIP+"::"+RevStr;
}
RevStr="";
//以下进行数据转发
if (TransmitStr!="")
{
bmsg=TransmitStr;
SendStr("asdasd",6);//Synchronize((TThreadMethod)&BC);
TransmitStr="";
}
}
}
catch(...)
{
return;
}
}
//---------------------------------------
int __fastcall MyServer::ReceiveStr(char * _Buf,int length) //接收数据
{
if(length<=0) return 0;
int aLen=0;
int pos=0;
char aBuf[255];
int smalllen=0;
if(length<=smalllen)
smalllen=length;
else
smalllen=SMALLLEN;
TWinSocketStream *pStream;
DWORD beginTick;
beginTick=GetTickCount();
while(!ClientSocket->Connected && GetTickCount()-beginTick<200);
try{
pStream = new TWinSocketStream(ClientSocket, 1000);
try{
if (pStream->WaitForData(TimeOutMSec)){
while(pStream->WaitForData(100))
{
Application->ProcessMessages();
if((aLen=pStream->Read(aBuf,smalllen)) == 0)
{
ClientSocket->Close();
break;
}
else{
aBuf[aLen]=0;
memcpy(_Buf+pos,aBuf,aLen);
pos+=aLen;
if(pos>=length)
break;
if(length-pos<smalllen) //promise get right byte no more no less
smalllen=length-pos;
}
}
}
else ClientSocket->Close();
}
__finally{
delete pStream;
}
}
catch(Exception &E){
Application->HandleException(this);
}
return pos;
}
//---------------------------------------
int __fastcall MyServer::SendStr(char * _Buf,int length)
{ //该函数未用到
if(length<=0)
return 0;
int SendLen=0;
TWinSocketStream *pStream;
DWORD beginTick;
beginTick=GetTickCount();
while(!ClientSocket->Connected && GetTickCount()-beginTick<200);
try{
pStream = new TWinSocketStream(ClientSocket, 1000);
try{
SendLen=pStream->Write(_Buf,length);
}
catch(Exception &E){
Application->HandleException(this);
}
}
__finally{
delete pStream;
}
return SendLen;
}
//---------------------------------------
void __fastcall MyServer::AddMessage() //将接收到的数据加入Memo1中
{
ServerFrm->Memo1->Lines->Add(Message);
}
//---------------------------------------
void __fastcall MyServer::BC() //数据转发
{
ServerFrm->boardcast(bmsg);
bmsg="";
}
//---------------------------------------