屏幕广播是学校我们小组正在做的小海豚的功能之一,这个功能的难点在于通信是一对多的传输。通信量太大,若一张图100KB,那么十台电脑就要传输1MB。这样的通信量在世纪钟明显是不可行的。
那么有什么办法呢。。第一个,我想得到就是屏幕分块传输。通过比对CRC的值里决定需不需要传输图片。
这里有一段网上搜索到的比对CRC的代码。
原文网址:http://blog.csdn.net/haart/article/details/7993239
先定义一个类。
class CCRC
{
public:
CCRC();
~CCRC();
// 计算缓冲区CRC
DWORD GetBufCrc32(LPBYTE lpBuf, DWORD dwSize);
// 计算区块CRC, 三个函数依次调用
void StartBlock(); // 初始化区块
BOOL AppendBlock(LPBYTE lpBuf, DWORD dwSize); // 增加区块
DWORD GetBlockCrc32(); // 返回当前CRC
// 计算文件的CRC
DWORD GetFileCrc32(LPCTSTR szFile);
protected:
void InitCrc32();
DWORD Reflect(DWORD dwRef, BYTE ch);
private:
DWORD m_dwCrc32Table[CRC32_TABLE_NUM];
DWORD m_dwCrc32Block;
};
类的函数定义
CCRC crc32;
CCRC::CCRC()
{
InitCrc32();
}
CCRC::~CCRC()
{
}
DWORD CCRC::Reflect(DWORD dwRef, BYTE ch)
{
DWORD value = 0;
for(int i = 1; i < (ch + 1); i++)
{
if(dwRef & 1)
value |= 1 << (ch - i);
dwRef >>= 1;
}
return value;
}
void CCRC::InitCrc32()
{
int i, j;
for (i = 0; i < CRC32_TABLE_NUM; i++)
{
m_dwCrc32Table[i] = Reflect(i, 8) << 24;
for (j = 0; j < 8; j++)
{
m_dwCrc32Table[i] = (m_dwCrc32Table[i] << 1) ^ (m_dwCrc32Table[i] & (1 << 31) ? CRC32_MAGIC : 0);
}
m_dwCrc32Table[i] = Reflect(m_dwCrc32Table[i], 32);
}
}
DWORD CCRC::GetBufCrc32(LPBYTE lpBuf, DWORD dwSize)
{
StartBlock();
if (AppendBlock(lpBuf, dwSize))
{
return GetBlockCrc32();
}
else
{
return CRC32_INVALID_VALUE;
}
}
void CCRC::StartBlock()
{
m_dwCrc32Block = CRC32_INVALID_VALUE;
}
BOOL CCRC::AppendBlock(LPBYTE lpBuf, DWORD dwSize)
{
if (NULL == lpBuf)
{
return FALSE;
}
DWORD i;
for (i=0; i<dwSize; i++)
{
m_dwCrc32Block = (m_dwCrc32Block >> 8) ^ m_dwCrc32Table[(m_dwCrc32Block & 0xFF) ^ lpBuf[i]];
}
return TRUE;
}
DWORD CCRC::GetBlockCrc32()
{
if (CRC32_INVALID_VALUE == m_dwCrc32Block)
{
return CRC32_INVALID_VALUE;
}
return (m_dwCrc32Block^CRC32_INVALID_VALUE);
}
DWORD CCRC::GetFileCrc32(LPCTSTR szFile)
{
StartBlock();
HANDLE hFile;
hFile = ::CreateFile(szFile,
GENERIC_READ,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD dwFileSize;
dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize > 0)
{
HANDLE hFileMapping;
hFileMapping = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (NULL != hFileMapping)
{
LPBYTE pbFile = (PBYTE)::MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if (NULL != hFileMapping)
{
AppendBlock(pbFile, dwFileSize);
::UnmapViewOfFile(pbFile);
}
::CloseHandle(hFileMapping);
}
}
::CloseHandle(hFile);
}
return GetBlockCrc32();
}
然后在main函数中的调用:
int ComCrc(char FileName1[],char FileName2[])
{
char szBuf[] = "123";
char sz[50];
crc32.GetBufCrc32((LPBYTE)szBuf, strlen(szBuf));
crc32.StartBlock();
crc32.AppendBlock((LPBYTE)szBuf, 1);
crc32.AppendBlock((LPBYTE)szBuf+1, 1);
crc32.AppendBlock((LPBYTE)szBuf+2, 1);
crc32.GetBlockCrc32();
if (crc32.GetFileCrc32(FileName1) == crc32.GetFileCrc32(FileName2)) return 1;
else return 0;
这样。把后一次截取的图片与前一次比较。如果相同,函数返回1,不同则返回0。之后再做处理。
这样。就能实现屏幕分块传输。。