1

我的服务器代码如下:

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 字节。

感谢任何帮助!谢谢

4

3 回答 3

2

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

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

这样,最后一次发送将具有正确的大小。

此外,如果您不使用任何标志,请使用 write 而不是 send。

于 2012-12-07T00:09:02.063 回答
0

您需要在读取端具有与写入端(bytes_written < filesize)类似的循环(即,虽然您可以读取更多字节,但您应该读取它们并附加它们)。

网络不保证一次 read() 调用将返回所有可用数据。

于 2012-12-07T00:02:41.570 回答
0

编写客户端-服务器套接字编程的最佳方式是在数据之前有一个标头。标头应说明将要传输的数据量。

例如,要发送数据“Hello World”,则发送为“0011+HELLO WORLD”

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

因此阅读器将进行两次读取: hRead = 5 /* 使用 5 您是说它可以从数据中读取最多 9999 个字节。read(sd, buff, hRead); dRead = atoi(buff); readn(sd, buff , d 读);

例如:服务器

 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);
  }

要发送消息:

  sprintf(buff, "%d + %d + %s\r\n", MSG_LOGIN, strlen("Hello World"), Hello World);
  sendn(sd, buff, strlen(buff));

客户:

 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);
}
于 2012-12-08T18:21:46.207 回答