0

奇妙な C プログラミングの問題をトラブルシューティングしようとしています。

クライアント プログラムで URL を入力し、その URL をサーバー プログラムに転送しています。唯一の問題は、サーバー プログラムが URL を受信したときに、最初の 2 文字が欠落していることです。したがって、URL がhttp://www.google.comの場合、サーバーが受け取るレポートは "tp://www.google.com" です。

奇妙なことは、部分的な送信の問題ではないということです。送信されたバイト数を確認していますが、メッセージ全体が送信されたと主張しています。問題は、受信側で、データの小さなチャンクを取得していると主張しているだけだということです。受信者は、メッセージ長 -2 を受信したことを報告します。受信側のコードは次のとおりです。

  printf("%s \n", "Connected. Receive length of URL to wget.");
  if ((messageSize = recv(acceptDescriptor, &urlLength, sizeof (int), 0)) == -1) {
    perror("recv URL length");
    exit(1);
  }
  urlSizeInt = atoi(urlLength);
  char url[urlSizeInt];
  printf("%s %d \n", "urlSizeInt: ", urlSizeInt);
  printf("%s \n", "Receive URL to wget.");

  if((messageSize = recv(acceptDescriptor, &url, 13, 0)) == -1) {
    perror("recv URL");
    exit(1);
  }

送信コード:

  printf("%s \n", "Connected");
  //connected to first stepping stone in the chain.
  //transfer the length of the URL
  if (send(socketDescriptor, urlLengthStr, strlen(urlLengthStr), 0) == -1){
    perror("send URL Length");
    exit(0);
  }

  //transfer the URL
  printf("%s %d \n", "strenlen(url): ",strlen(url));
  printf("%s %s \n", "url: ",url);
  int sent;
  int totalSent=0;
  if((sent=send(socketDescriptor, url, strlen(url), 0))==-1){
      perror("send URL");
      exit(0);
    }

  printf("%s %d \n", "sent: ",sent);


Send Output:
Connected
strenlen(url):  13
url:  http://www.cs
sent:  13

Receive Output:
Connected. Receive length of URL to wget.
urlSizeInt:  13
Receive URL to wget.
messageSize:  11
URL Received:  tp://www.cs

送信用に長さを char としてエンコードするコード:

char* url = "http://www.cs";
int urlLength  = strlen(url);
char* urlLengthStr;
sprintf(urlLengthStr, "%d", urlLength);
4

2 に答える 2

0

ソケットから読み取る場合、ファイルではなくストリームを読み取っています。ネットワーク コードを記述するための適切なガイドラインについては、こちらを参照してください。

送信側がすべてのデータを一度に送信したとしても、すべてのデータが一度に表示されるとは限りません。recv各呼び出しで受信したバイト数を考慮して、をループする必要があります。recv返された場合0、ソケットが閉じられたか、エラーが発生したため、そのソケットからデータを受信しなくなります。

これらのことを念頭に置いて...一種の疑似コード、私はこれをテストしませんでしたが、それがあなたにアイデアを与えることを願っています:

int expectedLength = readLengthFromSocket( socket, sizeof( int ) );
int bytesRead = 0;
char buffer[expectedLength];
bytesRead = recv( socket, buffer, ... );
runningLength = 0;
if( bytesRead < 1 )
    // Socket closed or there was an error, handle that here
else
{    runningLength += bytesRead;
     while( runningLength < expectedLength )
     {
         bytesRead = recv( socket, buffer + runningLength, ... );
         if( bytesRead < 1 )
            // Socket closed or there was an error, handle that here
            break;
         else
             runningLength += bytesRead;
     }
}

ネットワークを介した 、 、、および署名なしのバリアントの読み取りと書き込みには、通常、バイト スワップが必要であることに注意してintください。バイトのバッファを読み取ることはできません。longlong longshort

説明については、こちらを参照してください。

于 2013-10-07T20:23:53.820 に答える