不可能,肯定是你发的有问题,我以前做的传输2G文件,基本都没有损坏的,要是这样,肯定有问题。记得你的每个包的大小不能太多,否则会被截断成好几次请求。
我发的是一段完整视频,一帧一帧发,每一帧的大小是1MB外加20个字节的包头,服务端接收到之后就一帧一帧播放出来,肉眼看,接收到的视频还比较正常,但是看打印日志就发现两帧数据之间会出现一些乱七八糟的东西。
@carl_bruce: 你最好把你接收和发送的代码贴出来,你遇到的错误 99% 出在你的代码上。
@Launcher:
发送部分代码:
MSG_HEADER stMsgHeader; stMsgHeader.nChannel = nChannelNum; stMsgHeader.nDataSize = m_aryCompressedFrameInfo[nChannelNum].iSize; stMsgHeader.nMsgType = DATA_MEDIA; stMsgHeader.nReserved = stVAPacket.lPos; memcpy(m_pSendDataBuffer, &stMsgHeader, sizeof(MSG_HEADER)); memcpy(m_pSendDataBuffer+sizeof(MSG_HEADER),m_aryCompressedVideoBuffer[nChannelNum],m_aryCompressedFrameInfo[nChannelNum].iSize); if (m_pSendDataBuffer != NULL) { int ret = send(m_clientSocket, m_pSendDataBuffer, sizeof(MSG_HEADER) + PACK_SIZE,0); if (ret == SOCKET_ERROR) { return FALSE; } }
接收数据代码:
while (TRUE) { //接收数据 ret = recv(pAccept->m_serverSocket, pAccept->m_pDYFrameInfoBuffer, sizeof(MSG_HEADER)+PACK_SIZE, 0); if (ret == SOCKET_ERROR) { Sleep(40); continue; } PMSG_HEADER pMsg = (PMSG_HEADER)pAccept->m_pDYFrameInfoBuffer; unsigned int nMsgType = pMsg->nMsgType; unsigned int nChannel = pMsg->nChannel; unsigned int nDataSize = pMsg->nDataSize; unsigned int nFrameNo = pMsg->nReserved; CString strLog = _T(""); if ((tempFrameNo+1) != nFrameNo ) { strLog.Format(_T("SocketReceiver接收帧序号:%d不连续-----通道号:%d"), nFrameNo, nChannel); CCBLogOperator::DefaultInstance().AddLogEventToQueue(_LOG_EVENTNAME_SOCKET_SERVER, strLog, ECB_LOGEVENT_TYPE_INFO, _LOG_MODULENAME_SOCKET); strLog.Format(_T("第%d帧返回值%d---通道号:%d"),nFrameNo,ret,nChannel); CCBLogOperator::DefaultInstance().AddLogEventToQueue(_LOG_EVENTNAME_SOCKET_SERVER, strLog, ECB_LOGEVENT_TYPE_INFO, _LOG_MODULENAME_SOCKET); } /*strLog.Format(_T("SocketReceiver接收帧序号:%d-----通道号:%d"), nFrameNo, nChannel); CCBLogOperator::DefaultInstance().AddLogEventToQueue(_LOG_EVENTNAME_SOCKET_SERVER, strLog, ECB_LOGEVENT_TYPE_INFO, _LOG_MODULENAME_SOCKET);*/ switch(nMsgType){ case DATA_MEDIA: pAccept->AddBufferCache(nChannel,pAccept->m_pDYFrameInfoBuffer, nDataSize); tempFrameNo = nFrameNo; ZeroMemory(pAccept->m_pDYFrameInfoBuffer,sizeof(MSG_HEADER) + PACK_SIZE); break; } }
部分输出日志:
07-25 17:47:05:507,运行日志,Socket服务端,,,,,SocketReceiver接收帧序号:-390590141不连续-----通道号:-1505726696 07-25 17:47:05:538,运行日志,Socket服务端,,,,,第-390590141帧返回值16060---通道号:-1505726696 07-25 17:47:05:539,运行日志,Socket服务端,,,,,SocketReceiver接收帧序号:-1195319992不连续-----通道号:1530607119 07-25 17:47:05:540,运行日志,Socket服务端,,,,,第-1195319992帧返回值7300---通道号:1530607119 07-25 17:47:05:541,运行日志,Socket服务端,,,,,SocketReceiver接收帧序号:-415549683不连续-----通道号:-742952285 07-25 17:47:05:543,运行日志,Socket服务端,,,,,第-415549683帧返回值2920---通道号:-742952285 07-25 17:47:05:544,运行日志,Socket服务端,,,,,SocketReceiver接收帧序号:471110329不连续-----通道号:1503187261 07-25 17:47:05:544,运行日志,Socket服务端,,,,,第471110329帧返回值4380---通道号:1503187261 07-25 17:47:05:545,运行日志,Socket服务端,,,,,SocketReceiver接收帧序号:722354374不连续-----通道号:983222349 07-25 17:47:05:545,运行日志,Socket服务端,,,,,第722354374帧返回值7300---通道号:983222349 07-25 17:47:05:545,运行日志,Socket服务端,,,,,SocketReceiver接收帧序号:1986516248不连续-----通道号:-652829758 07-25 17:47:05:546,运行日志,Socket服务端,,,,,第1986516248帧返回值7300---通道号:-652829758 07-25 17:47:05:546,运行日志,Socket服务端,,,,,SocketReceiver接收帧序号:-1461356357不连续-----通道号:-1794270355 07-25 17:47:05:546,运行日志,Socket服务端,,,,,第-1461356357帧返回值7300---通道号:-1794270355 07-25 17:47:05:547,运行日志,Socket服务端,,,,,SocketReceiver接收帧序号:-1916456746不连续-----通道号:2027623460 07-25 17:47:05:547,运行日志,Socket服务端,,,,,第-1916456746帧返回值7300---通道号:2027623460 07-25 17:47:05:547,运行日志,Socket服务端,,,,,SocketReceiver接收帧序号:-577789989不连续-----通道号:1163987280
@carl_bruce: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx
函数 recv 的返回值不为SOCKET_ERROR 时,表示实际接收到的数据的大小,此大小不一定等于 sizeof(MSG_HEADER) + PACK_SIZE,因此当你解析数据包的时候,你要根据 recv 返回的长度确定是否收到了完整的数据包。
你是不是多个接受写同一个日志了?
TCP连接是安全的,你服务端能且只能收到客户端发出的数据
确实是多个接收写同一个日志了,但这个有问题么?
我共开了三个端口接收数据,哪个端口接收的是第几个包,日志里面都有记录,这个看的很清楚。现在的问题是:比如刚是第0个端口接收的是第100个包的数据,接下来应该是第0个端口接收第101个包的数据或者,第1个端口接收第n个包的数据才对,但是日志里面却记录了很多条类型第8779900个端口接收的是第4798877个包的数据,很奇怪。
@carl_bruce: 你服务器是开了1个端口,客户端连接了多次,还是服务器开多个端口每个客户端连接不同端口?
你应该检查一下你做日志的代码.
想测试连接,还是下个现成的抓包工具吧,简单粗暴方便直接
@吴瑞祥: 刚开始是服务器开了一个端口,客户端连接了多次,现在是服务器开了三个端口,三个客户端分别连接,效果都一样。
做日志的代码很简单,就是把recv到的数据包的包头进行分析,把端口号和第几个包打印出来。
确实是发送的数据被截成了多段