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

送信部分にバグがあります。ファイルから送信するバイトが1バイト残っていると、送信するコンテンツが保存されているメモリ領域からさらに送信されるため、newLengthを更新する必要があります。次のように修正する必要があります。

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

このようにして、最後の送信は正しいサイズになります。

また、フラグを使用していない場合は、送信の代わりに書き込みを使用してください。

于 2012-12-07T00:09:02.063 に答える
0

書き込み側と同様のループ (bytes_written < filesize) を読み取り側でも行う必要があります (つまり、より多くのバイトを読み取ることができますが、それらを読み取って追加する必要があります)。

ネットワークは、1 回の read() 呼び出しが利用可能なすべてのデータを返すことを保証しません。

于 2012-12-07T00:02:41.570 に答える
0

クライアント サーバー ソケット プログラミングを記述する最善の方法は、データの前にヘッダーを配置することです。ヘッダーには、転送するデータの量が記載されている必要があります。

例えば、「He​​llo World」というデータを送信する場合は、「0011+HELLO WORLD」として送信します。

ここで 11 は、送信者が現在送信しようとしているデータのサイズを表します。最初の 4 バイトを読み取った受信者は、送信者から次の 11 バイトのデータを読み取る準備ができていることを理解できます。

hRead = 5 /* 5 の場合、データから最大 9999 バイトまで読み取ることができると言っている". read(sd, buff, hRead); dRead = atoi(buff); readn(sd, buff 、dRead);

例: サーバー

 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 に答える