我在编程的时候遇见了一个很奇怪的问,发送出去的数据和接收到的数据不一样!具体来说是这样的,我编写了一个发文件的程序。经测试,这个程序可用,发个几兆的文件也不成问题。然后想在此程序的基础出加入对文件的HASH,接收方接收到文件并在本地作HASH后,与传过来的HASH作比较,如果想等,则认为收的数据未被篡改;如果不相等,则认为数据遭到篡改,发出警告。我不明白我的程序为什么出现了发送的数据的HASH值与接收到的不一样?
程序实现具体实现如下:
发送方:
while(FileLeft > MAX_FILE_BLOCK)
{
file.Read(data,MAX_FILE_BLOCK); //对传送数据做HASH
char hash_buff[HASH_LEN] = "\0";
HASH(data, hash_buff);

FileSend = send(socketSend, data, MAX_FILE_BLOCK, 0);
FileSend = send(socketSend, hash_buff, HASH_LEN, 0);
        }接收方:
while(FileLeft > MAX_FILE_BLOCK)
{
char recv_hash[HASH_LEN + 1] = "\0"; FileRec = recv(socketSend, data, MAX_FILE_BLOCK, 0);
// Sleep(10);
FileRec = recv(socketSend, recv_hash, HASH_LEN, 0);
// Sleep(10); char hash[HASH_LEN + 1] = "\0";
HASH(data, hash); if(!strcmp(hash, recv_hash))
{
                    ……
                }
else
{
MessageBox(NULL,"文件被篡改!","文件",MB_OK);
return 0;
}
           }
    文件是分块发送的。
    很奇怪的现在是,如果单独调试发送方或接收方,程序都会发出“文件被篡改”的警告;但如果是同时调试发送方和接收方,就不会发出警告。
如果将一次发送的块的大小,即MAX_FILE_BLOCK由原来的1024改大到2048时,程序报警的时刻就比1024时推迟很多。举例来说,块大小为1024时,程序可能在第二次循环时报警;增大为2048时,可能在第5次时报警。(只是打个比方,具体数值是多少不好弄清楚,呵呵~~)。
    而且,我发现,在我朋友的电脑上,如果块大小增大为2048时,程序运行正确;在我机子上,程序就不正确。这难还与机子有关?
    经过调试,发现与文件发送与接收的快慢无关……

解决方案 »

  1.   

    确保你发送、接收完数据了    如下例,send也采用类似的方式
    int  nRecvLen = 0;
    int  nFileLen = MAX_FILE_BLOCK;
    while(nFileLen > 0)
    {
         nRecvLen += recvrecv(socketSend, data, nFileLen , 0); 
         nFileLen -= nRecvLen;
    }
      

  2.   

    按照你的代码,你的数据总是MAX_FILE_BLOCK的整数倍,不考虑这种情况之外的可能?
      

  3.   

    发送一次若尺寸为2048,接收不一定为一次就是2048,假设为1455,则剩下的593可能与下一个数据包合并接收到,所以HASH值就不同了,你应该等文件接收完成后再计算HASH值比较。TCP接收/发送时不要假设为发送一次,对端就接收到一次,倘若如此假设则网络通讯程序做不好。