Hey Andy, I can see two problems with your code:
* In your sending loop, you got three 'return' statements where you may exit the function without unlocking your global thread lock. The cases may be rare, but if that happens it will lead to problems. A common solution for this problem is to use a thread locker object on the stack that will unlock on destruction and thereby automatically unlock whenever your function returns. * In your receiving code, you lock the global thread lock only in some specific cases. However, since enet is not thread-safe you need to wrap the whole while loop with a lock (including enet_host_service). In general it seems you're only protecting access to your mRecvBuffer and mSendBuffer, but you need to realize enet doesn't do any locking on its own data types either. Some additional hints: * Consider having just one thread that does both sending and receiving. What are you trying to achieve by separating this? If you would do that you wouldn't need to do locking for enet and protecting your send/receive buffers would be enough. * Note that you generally do not need to use a thread for enet at all. You can pass a 0-timeout to enet_host_service and call it regularly from your main thread instead. That would avoid the whole locking stuff. Regards, Bjørn On Mon, May 27, 2013 at 4:53 AM, Andy Zheng <[email protected]> wrote: > hi,sorry to reply such late! > I put send and receive in two different threads > here is the part of sending: > while (!mSendBuffer.isEmpty() && mConnect) > { > if(safety) > GlobalThreadLock.Lock(); > PacketBuffer* pack = mSendBuffer.getFront(); > > const char* pszText = (const char*)pack->buf.base(); > //ELOG("buf :%s",pszText); > if(NULL == pszText) > { > ELOG("send buf is null"); > continue; > } > ENetPacket > *packet=enet_packet_create(pszText,strlen(pszText)+1,ENET_PACKET_FLAG_RELIABLE); > > if (NULL == mPeer) > { > ELOG("mPeer is NULL"); > return; > } > int channle = rand()%mChannelLimit; > if(pack->flags) > enet_host_broadcast(mHost ,channle ,packet); > else > { > int reval = enet_peer_send(mPeer,channle,packet); > > if (reval != 0) > { > ELOG("send msg failed"); > return; > } > } > pack->buf.clear(); > delete pack; > mSendBuffer.dequeue(); > if(safety) > GlobalThreadLock.Unlock(); > } > > and here is the part of receiving: > > while(enet_host_service(mHost,&mEvent,mRecvDelay)>=0) > { > if(Thread_Pause) > { > ELOG("Thread wait"); > GlobalThreadLock.wait(); > } > if(mEvent.type==ENET_EVENT_TYPE_CONNECT) > { > if(mType == SERVER) > { > if(safety) > GlobalThreadLock.Lock(); > static unsigned int num=0; > ENetAddress remote=mEvent.peer->address; > char ip[256]; > enet_address_get_host_ip(&remote,ip,256); > ELOG("ip: %s has been connected, NO.: %d ,port: %d",ip,num,remote.port); > mEvent.peer->data=(void*)num++; > ELOG("user data: %d",mEvent.data); > if(NULL == mPeer) > mPeer = mEvent.peer; > mConnect = true; > if(safety) > GlobalThreadLock.Unlock(); > } > } > else if(mEvent.type==ENET_EVENT_TYPE_RECEIVE) > { > if(safety) > GlobalThreadLock.Lock(); > > if (mRecvBuffer.isFull()) > { > DequeueRecvBuf(); > } > > PacketBuffer* packet = new PacketBuffer; > packet->flags = 0; > packet->buf.push((const char*)mEvent.packet->data > ,mEvent.packet->dataLength); > mRecvBuffer.enqueue(packet); > > enet_packet_destroy(mEvent.packet); > > if(safety) > GlobalThreadLock.Unlock(); > } > else if(mEvent.type==ENET_EVENT_TYPE_DISCONNECT) > { > ENetAddress remote=mEvent.peer->address; > char ip[256]; > enet_address_get_host_ip(&remote,ip,256); > if(mType == CLIENT) > { > ELOG("NO. %d remote has closed connection",mEvent.peer->data); > if (!mInitiative) > { > mConnect = false; > CallBack(NET_DisConnectWithServer,ip); > } > } > else if(mType == SERVER) > { > CallBack(NET_ClientDisConnect,ip); > ELOG("NO. %d remote has closed connection",mEvent.peer->data); > } > } > } > > > 2013/5/25 Payton Turnage <[email protected]> >> >> Can you post a block of relevant code or link to a gist? Also, note that >> enet_peer_send does not actually send anything, but just queues it. If it >> returns 0 it means the packet was successfully queued, and enet_host_service >> will send it on the next opportunity. >> >> >> On Thu, May 23, 2013 at 11:22 PM, [email protected] <[email protected]> >> wrote: >>> >>> I got a issue recently ,it happened randomly,but the probability is very >>> small。 >>> when I created a client and connect to server success,send and receive is >>> all normal,but the client suddenly can`t send the buffer at a moment and >>> still can receive buf,I check the enet_peer_send function it return 0 ,it`s >>> means sending normal.,I wonder if the issue is caused by server >>> >>> ________________________________ >>> [email protected] >>> >>> _______________________________________________ >>> ENet-discuss mailing list >>> [email protected] >>> http://lists.cubik.org/mailman/listinfo/enet-discuss >>> >> > > > _______________________________________________ > ENet-discuss mailing list > [email protected] > http://lists.cubik.org/mailman/listinfo/enet-discuss > _______________________________________________ ENet-discuss mailing list [email protected] http://lists.cubik.org/mailman/listinfo/enet-discuss
