第一:ioctlsocket设定了非阻塞套接字后,accpet接收时未接收完会直接返回,而需要将剩下的数据接收完是否还要手动调用accept?还是只使用一次accept
第二:客户端send,服务器accept,怎么判断接收数据完整长度。。
(希望能简单给下这两个部分的代码)
第二:客户端send,服务器accept,怎么判断接收数据完整长度。。
(希望能简单给下这两个部分的代码)
解决方案 »
- 请问用VC怎么写一个生成EXE自执行文件的EXE文件??
- 问个貌似很简单的sql问题,可是我却找不到简便的方法
- 问一个比较菜的问题!VC中的CString类可以忽略大小写 Find吗?请指教
- 如何将CString 12345678 转化成 DWORD dw=0x12345678?
- 如何设置在应用程序主窗口显示前弹出登录框,进行身份验证啊?
- 用API怎么实现HBITMAP90度,180度,270度等旋转。
- ReleaseMutex、ResetEvent运行失效,请高手指点
- Exe文件运行时怎么对它进行修改?
- 如何获得线程的退出代码,或者确切知道线程已经执行完毕.
- 鼠标单击获得当前点坐标后如何用afxmessage将其输出
- 如何让MFC改变默认文档操作方式??
- 有一个usb的无线网卡,请问如何编程实现抓取到经过无线网卡上的数据包, windows环境?
第二个问题,你在客户端发送时可以在数据的前是个字节放上数据长度totalLength,之后才是真是数据,然后服务端先读取一段数据,之后取出前是个字节的内容,然后就开始数数了,只memcpy totalLength个字节 代码 明天抽时间给你贴点 要给分的
这相当于客户端的
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;
这相当于服务端的
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;
}
}