第一:ioctlsocket设定了非阻塞套接字后,accpet接收时未接收完会直接返回,而需要将剩下的数据接收完是否还要手动调用accept?还是只使用一次accept
第二:客户端send,服务器accept,怎么判断接收数据完整长度。。
(希望能简单给下这两个部分的代码)

解决方案 »

  1.   

    如果是设置成非阻塞套接制,那你accept后还要用select看看是否有连接练过来,就是设个fd_set看它是否可读了。。你也可以设置成阻塞的,就少了select的步骤了。。我是这么想的。。
    第二个问题,你在客户端发送时可以在数据的前是个字节放上数据长度totalLength,之后才是真是数据,然后服务端先读取一段数据,之后取出前是个字节的内容,然后就开始数数了,只memcpy totalLength个字节 代码 明天抽时间给你贴点  要给分的 
      

  2.   


    这相当于客户端的
                        int structureSize = sizeof(AlertDetail);
                        int alertXMLlength = 0;
                        int customResponseFieldlength = 0;
    int AreaOfInterestEventSynopsisPointsLength = sizeof(Point)*detail->areaOfInterestEventSynopsis.pointsNum;
    int AreaOfInterestEventSynopsisActionsLength = 50*detail->areaOfInterestEventSynopsis.ActionsNum;
                        int totalImageLength=detail->targetSlices.slice1.snapshotSize+detail->targetSlices.slice2.snapshotSize;
                        if (NULL!=detail->alertXML)
                        {
                            alertXMLlength = strlen(detail->alertXML);
                        }
                        if (NULL!=detail->customResponseField)
                        {
                            customResponseFieldlength=strlen(detail->customResponseField);
                        }
                        int totalLength = structureSize+totalImageLength+alertXMLlength+customResponseFieldlength+AreaOfInterestEventSynopsisPointsLength+AreaOfInterestEventSynopsisActionsLength+32;
                        char * alertData = new char[totalLength];
                        if(alertData)
                        {
                            if(detail->targetSlices.slice1.snapshotData.vt==(VT_ARRAY|VT_UI1))   
                            {
                                char*pBuf=NULL;;
                                SafeArrayAccessData(detail->targetSlices.slice1.snapshotData.parray,(void **)&pBuf);   
                                memcpy(alertData+32+structureSize,pBuf,detail->targetSlices.slice1.snapshotSize); 
                                SafeArrayUnaccessData(detail->targetSlices.slice1.snapshotData.parray);   
                            }                        if(detail->targetSlices.slice2.snapshotData.vt==(VT_ARRAY|VT_UI1))   
                            {
                                char*pBuf=NULL;;
                                SafeArrayAccessData(detail->targetSlices.slice2.snapshotData.parray,(void **)&pBuf);   
                                memcpy(alertData+32+structureSize+detail->targetSlices.slice1.snapshotSize,pBuf,detail->targetSlices.slice2.snapshotSize); 
                                SafeArrayUnaccessData(detail->targetSlices.slice2.snapshotData.parray);   
                            }                        memcpy(alertData,&totalLength,4);
                            memcpy(alertData+4,&structureSize,4);
                            memcpy(alertData+8,&(detail->targetSlices.slice1.snapshotSize),4);
                            memcpy(alertData+12,&(detail->targetSlices.slice2.snapshotSize),4);
                            memcpy(alertData+16,&alertXMLlength,4);
                            memcpy(alertData+20,&customResponseFieldlength,4);
    memcpy(alertData+24,&AreaOfInterestEventSynopsisPointsLength,4);
    memcpy(alertData+28,&AreaOfInterestEventSynopsisActionsLength,4);
                            memcpy(alertData+32,detail,structureSize);
                            //拷贝警告XML文本
                            int alertXMLOffset= 32+structureSize+detail->targetSlices.slice1.snapshotSize+detail->targetSlices.slice2.snapshotSize;;
                            if (NULL!=detail->alertXML)
                            {
                                memcpy(alertData+alertXMLOffset,detail->alertXML,alertXMLlength);
                            } int customResponseFieldOffset = alertXMLOffset+alertXMLlength;
                            if (NULL!=detail->customResponseField)
                            {
                                //拷贝自定义xml文本 
                                memcpy(alertData+customResponseFieldOffset,detail->customResponseField,customResponseFieldlength);
                            } if (strncmp(detail->eventType,"AreaOfInterestEventSynopsis",strlen("AreaOfInterestEventSynopsis"))==0)
    {
    if (NULL!=detail->areaOfInterestEventSynopsis.points&&NULL!=detail->areaOfInterestEventSynopsis.Actions
    &&0!=AreaOfInterestEventSynopsisPointsLength&&0!=AreaOfInterestEventSynopsisActionsLength)
    {
    int AreaOfInterestEventSynopsisPointsOffset = customResponseFieldOffset+customResponseFieldlength;
    memcpy(alertData+AreaOfInterestEventSynopsisPointsOffset,detail->areaOfInterestEventSynopsis.points,AreaOfInterestEventSynopsisPointsLength);
    int AreaOfInterestEventSynopsisActionsOffset = AreaOfInterestEventSynopsisPointsOffset+AreaOfInterestEventSynopsisPointsLength;
    memcpy(alertData+AreaOfInterestEventSynopsisActionsOffset,detail->areaOfInterestEventSynopsis.Actions[0],AreaOfInterestEventSynopsisActionsLength);
    }
    }
    AlertDetail * aa= (AlertDetail*)(alertData+32);
                            //向客户端发送
                            for(int clientIndex =0;clientIndex<clientSocketList.size();clientIndex++)
                            {
                                SOCKET clientSocket = 0;
                                clientSocket = clientSocketList[clientIndex];
                                DataSend(clientSocket,alertData,totalLength);
                                Sleep(100);
                            }
                            
                            //Sleep(300);
                            delete []alertData;
                            alertData=NULL;
      

  3.   


    这相当于服务端的 
                while (1)
                {
                    FD_ZERO(&Fd_Read);
                    FD_SET(connectToServerSocket, &Fd_Read);
                    int ret=0, nRecv=0;
                    if (hasObtainedTotalCount&&(charReceived==totalcharCount))
                    {
                        if (charReceived>0)
                        {
                            ifDataReceived = true;
                        }
                        break;
                    }                ret = select(FD_SETSIZE, &Fd_Read, NULL, NULL, NULL);
                    if(ret <= 0)
                    {
                        if (charReceived>0)
                        {
                            ifDataReceived = true;
                        }
                        break;
                    }                //从服务端接收数据
                    if(FD_ISSET(connectToServerSocket, &Fd_Read))
                    {
                        // printf("从客户端接受数据\n");
                        nRecv = recv(connectToServerSocket, RecvBuf, sizeof(RecvBuf), 0);
                        if(nRecv <= 0)
                        {
                            if (charReceived>0)
                            {
                                ifDataReceived = true;
                            }
                            //检测到断开连接后客户端自动重连  ret==1 nRecv小于0
                            //::MessageBox(NULL,"服务器断开,客户端服务线程退出","",0);
    closesocket(connectToServerSocket);
    if (NULL!=DataBufferReceivedData.ReceivedData)
    {
    delete []DataBufferReceivedData.ReceivedData;
    DataBufferReceivedData.ReceivedData = NULL;
    }
    goto connect;
                        }                    if (NULL!=DataBufferReceivedData.ReceivedData)
                        {
    //如果缓冲区不够,重新申请
    if (charReceived+nRecv >= receiveBufferLength) 
    {
    int times = ((int)((charReceived+nRecv)/receiveBufferLength)+1)*3;
    //内存空间增倍
    tempBuffer = new char[receiveBufferLength * times];
    memset(tempBuffer,0,receiveBufferLength * times);
    memcpy(tempBuffer,DataBufferReceivedData.ReceivedData,charReceived);
    receiveBufferLength = receiveBufferLength * times;
    delete []DataBufferReceivedData.ReceivedData;
    DataBufferReceivedData.ReceivedData = tempBuffer;
    tempBuffer = NULL;
    } //把当前收到数据追加到buffer末尾
    memcpy(DataBufferReceivedData.ReceivedData+charReceived,RecvBuf,nRecv);
    charReceived += nRecv;
    //如果字符数大于260则取出在这里面的总字节数信息 以便看是否传送完成
    if (!hasObtainedTotalCount&&charReceived>=16)
    {
    //取出0到3四个字节的总字节数信息
    memcpy(&totalcharCount,DataBufferReceivedData.ReceivedData,sizeof(size_t));
    hasObtainedTotalCount=true;
    }
                        }
                    }
                }            if (ifDataReceived)
                {
    AlertReceived();
    //::MessageBox(NULL,"收到数据,已经写入文件~~~","提示",0);
    DWORD timerThreadId = 0;
    //闪烁和声音提示  alreadyHasATimer和timerOver确保当已经有提示时如果再有警告来则不再提示
    if (!alreadyHasATimer&&!timerOver)
    {
    alreadyHasATimer = true;
    timerOver = false;
    //线程实现 马上返回
    CreateThread(NULL,NULL,TimerProc,(LPVOID)(0),0,&timerThreadId);
    }
    delete []DataBufferReceivedData.ReceivedData;
    DataBufferReceivedData.ReceivedData=NULL;
                }
            }
      

  4.   

    wangxuqing大侠回答真完善。。谢谢啦,小小积分全给你了