C 客户端读取的字节数少于服务器在套接字上发送的字节数

C 客户端读取的字节数少于服务器在套接字上发送的字节数,c,sockets,C,Sockets,我的服务器代码如下: while(bytes_written < filesize){ //Send from send_ptr bw = send(child_socket, send_ptr, newLength, 0); printf("%d bytes written\n", (int)bw); //Increment by

我的服务器代码如下:

while(bytes_written < filesize){
                    //Send from send_ptr
                    bw = send(child_socket, send_ptr, newLength, 0);
                    printf("%d bytes written\n", (int)bw);
                    //Increment bytes written
                    bytes_written += bw;
                    //Move send pointer
                    send_ptr = send_ptr + bw;
}
while((num_bytes_recv = read(sd, jpgBufferPointer, BUFFER_LENGTH))>0){
        total_bytes_recv += num_bytes_recv;
        printf("Read %d bytes\n",num_bytes_recv);

        //Check for error
        if(jpgError == NULL)
            jpgError = strstr(jpgBufferPointer, "404 Not Found");

        if(jpgError != NULL){
            //Forwarding error response
            if(send(sd, jpgBuffer, num_bytes_recv, 0) == -1){
                error("Failed to send response message to client"); 
            }
        }   
        else{
            //Find content size
            contentSizeBuffer = strstr(jpgBufferPointer,"Content-Length");

            if(contentSizeBuffer != NULL){
                contentSizeBuffer=contentSizeBuffer+16;
                contentSize=atoi(contentSizeBuffer);                    
                jpgBuffer=(char*)realloc(jpgBuffer,(contentSize+FILE_NAME_LENGTH*2)*sizeof(char));
                jpgBufferPointer=jpgBuffer;
            }
            jpgBufferPointer+=num_bytes_recv;
        }
    }
服务器说它已经发送了所有43000字节,但客户端说它只收到32768字节


谢谢你的帮助!谢谢

您需要像在写入端(bytes_writed
网络不保证一次read()调用将返回所有可用数据。

如果发送部分有错误,则应更新newLength,因为如果文件中还有1个字节要发送,它将发送更多数据,超出存储要发送内容的内存区域。您应该以这种方式修复:

bw = send(child_socket, send_ptr, newLength<(filesize-bytes_written)?newLength:(filesize-bytes_written), 0);

bw=send(child_socket,send_ptr,newLength编写客户机-服务器套接字编程的最佳方法是在数据之前有一个标头。标头应说明要传输的数据量

例如,发送数据“Hello World”,然后将其作为“0011+Hello World”发送

这里11代表发送方现在计划发送的数据的大小。在读取前4个字节时,接收方可以理解他应该准备好从发送方读取下11个字节的数据

所以读者会做两件事: hRead=5/*使用5表示它最多可以从数据中读取9999字节”。 读取(sd、buff、hRead); 恐惧=原子(浅黄色); 阅读(sd,buff,恐惧)

例如:服务器

 size_t sendn(int fd, const void *vptr, size_t n) {
   size_t nleft;
   size_t nwritten;
   const char *ptr;

   ptr = vptr;
   nleft = n;
   while (nleft > 0) {
       if ((nwritten = send(fd, vptr, nleft, 0)) <= 0) {
          if (errno == EINTR)
               nwritten = 0;
          else {
              fprintf(stderr, "send failed  %d - %s\n", fd, strerror(errno));
              return (-1);
          }
        }
        nleft -= nwritten;
        ptr += nwritten;
   }
   return (n);
  }
客户:

 size_t readn(int fd, void *vptr, size_t n) {
  size_t nleft;
  size_t nread;
  char *ptr;

  ptr = vptr;
  nleft = n;
  while (nleft > 0) {
      if ((nread = recv(fd, ptr, nleft, 0)) < 0) {
          if (errno == EINTR)
              nread = 0;
          else {
              fprintf(stderr, "read failed %d - %s\n", fd, strerror(errno));
              return (-1);
          }
      } else if (nread == 0)
          break;

      nleft -= nread;
      ptr += nread;
  }
  return (n - nleft);
}
size\u t readn(intfd,void*vptr,size\u t n){
尺寸(左);;
尺寸(单位:nread);
char*ptr;
ptr=vptr;
nleft=n;
而(nleft>0){
如果((nread=recv(fd,ptr,nleft,0))<0){
如果(errno==EINTR)
nread=0;
否则{
fprintf(stderr,“读取失败%d-%s\n”,fd,strerror(errno));
返回(-1);
}
}如果(nread==0),则为else
打破
nleft-=nread;
ptr+=nread;
}
返回(n-nleft);
}

每当我看到一个很好的二次幂时,我都会怀疑。这不是你的
缓冲区长度,是吗?我的缓冲区长度是100000。^ while((num\u bytes\u recv=read(sd,jpgBufferPointer,BUFFER\u LENGTH))>0)不是这样做的吗?这对我几乎有效。同样的问题出现在:while(bytes\u writed size_t readn(int fd, void *vptr, size_t n) {
  size_t nleft;
  size_t nread;
  char *ptr;

  ptr = vptr;
  nleft = n;
  while (nleft > 0) {
      if ((nread = recv(fd, ptr, nleft, 0)) < 0) {
          if (errno == EINTR)
              nread = 0;
          else {
              fprintf(stderr, "read failed %d - %s\n", fd, strerror(errno));
              return (-1);
          }
      } else if (nread == 0)
          break;

      nleft -= nread;
      ptr += nread;
  }
  return (n - nleft);
}