套接字校验和问题

时间:2013-04-29 22:10:40

标签: c sockets tcp checksum

这可能是一个简单的解决方案,但基本上我正在使用TCP将二进制文件逐个发送到另一个程序并检查以确保校验和与有效性匹配。问题是收到的校验和绝不是从提交的最后一部分(剩余部分)中发送的校验和。

发件人的代码片段是:

void* buffer = (void *)malloc(BLOCKSIZE+1);
if (!buffer)
  error("Error: malloc error for buffer.\n");
fread(buffer, BLOCKSIZE, 1, fp_read);  //read from binary file for the current block.
int checksum = checksum(buffer,BLOCKSIZE);
n = write(sockfd,buffer,BLOCKSIZE);
if (n < 0)
  error("ERROR writing to socket");

接收者是:

void* buffer = (void *)malloc(BLOCKSIZE+1);
if (!buffer)
  error("Error: malloc error for buffer.\n");
n = read(sockfd,buffer,BLOCKSIZE);
if (n < 0)
  error("Error: reading from socket.");
int checksum = checksumv(buffer,BLOCKSIZE);

有人发现它有什么问题吗?校验和匹配的唯一部分是最终部分,它没有完全填满缓冲区。

感谢。

发件人的整个代码是:

FILE* fp_read = fopen("file.jpg", "rb");
if (fp_read == NULL)
  error("Cannot open the file for peer piece download.");

fseek(fp_read, 0, SEEK_END);
unsigned long fileLen = ftell(fp_read);
fseek(fp_read, 0, SEEK_SET);

int checksum, loops = fileLen / BLOCKSIZE;
int remainder = fileLen % BLOCKSIZE;
int segment_num = loops+1;

void* buffer4 = (void *)malloc(BLOCKSIZE+1);
    if (!buffer4)
      error("Error: malloc error for buffer.\n");

    int i, sent = 0;
    for (i=1; i<=loops; i++)
    {
      fread(buffer4, BLOCKSIZE, 1, fp_read);
      checksum = checksumv(buffer4,BLOCKSIZE);

      n = write(sock,buffer4,BLOCKSIZE);
      if (n < 0)
        error("ERROR writing to socket");
    }
    if (remainder > 0)
    {
      //Allocate memory
      void* buffer5 = (void *)malloc(remainder+1);
      if (!buffer5)
        error("Error: malloc error for buffer2.\n");

      fread(buffer5, remainder, 1, fp_read);
      checksum = checksumv(buffer5,remainder);

      n = write(sock,buffer5,remainder);
      if (n < 0)
        error("ERROR writing to socket");
    }

2 个答案:

答案 0 :(得分:1)

当您阅读数据时:

n = read(sockfd,buffer,BLOCKSIZE);
if (n < 0)
  error("Error: reading from socket.");
int checksum = checksumv(buffer,BLOCKSIZE);

您需要尊重read()表示放入buffer的字节数 - 在返回之前,它可能会读取少于BLOCKSIZE个字节的数量。

另外,我没有看到校验和发送(或接收)的位置 - 我只看到正在发送的文件数据。你如何比较校验和?

最后,由于TCP是一种流媒体协议,因此您需要有一些方法在文件数据完成时向接收方指示,例如通过在文件数据之前发送大小,或者使用某些“带外”指示。

答案 1 :(得分:0)

您没有正确累积校验和,但是复制文件并不需要所有这些复杂性:

byte buffer[8192];
while ((count = fread(buffer, sizeof buffer, 1, fp)) > 0)
{
    n = write(sock,buffer4,count);
    if (n < 0)
      error("ERROR writing to socket");
    checksum += checksumv(buffer, count); // or possibly ^=, it depends how your checksum is supposed to accumulate
}