屏幕广播是学校我们小组正在做的小海豚的功能之一,这个功能的难点在于通信是一对多的传输。通信量太大,若一张图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。之后再做处理。
这样。就能实现屏幕分块传输。。