-1

私のプログラムで奇妙なことが起こっていますが、何をすべきかわかりません。これは、これまでの私のコードの疑似コードバージョンです。

サーバ:

//Set up Server sockets

int maximum;

// Collect the maximum
cout << "\nEnter a Maximum:";
cin >> maximum;
cout << "\n";

int *array = new int[maximum + 1];

memset(array, 0, sizeof(array));

while(array[0] < anInt){

    //receive the array from the client
    if(recv(newsockfd, array, maximum, 0) < 0){
        perror("ERROR receiving from socket");
    }

    mathFunction(array);  //A function that alters the contents of array
    array[0]++;

    //If array[0] isn't too big
    if(array[0] < anInt){
        // Send the array to the client
        if(send(newsockfd, array, maximum, 0) < 0){
            perror("ERROR sending to socket");
        }
    }
}

クライアント:

//Set up Client sockets

//The maximum was already sent over earlier
int *array = new int[maximum + 1];

while(array[0] < anInt){

    //receive the array from the server
    if(recv(sockfd, array, maximum, 0) < 0){
        perror("ERROR receiving from socket");
    }

    mathFunction(array);  //A function that alters the contents of array
    array[0]++;

    if(send(sockfd, array, maximum, 0) < 0){
        perror("ERROR sending to socket");
    }
}

私の問題は、「ピアによる接続リセット」エラーが発生し続けることです。これにより、セグメンテーション違反が発生し、プログラムがクラッシュします。また、send / recv関数の3番目の引数(現在はmaximumに設定されています)をいじってみると、プログラムの動作が異なります。ユーザーが最大100を入力すると、実際には完全に機能しますが、それ以上のものはそれを台無しにします。

私はこれがロングショットであることを知っていますが、誰かが私が間違っていることを見ることができますか?

4

2 に答える 2

1

明らかに間違っていると思われることの 1 つは、次のとおりです。

mathFunction(array);

mathFunction()配列内の要素数はわかりません。実際、この情報をどこにも保存しないことで、呼び出し時にこの情報を破棄recv()します (コードで行うことは、ゼロ未満かどうかを確認するだけで、正の場合は使用しません)。を呼び出す場合、コードは1 から までの任意のバイト数recv()を受け取る準備ができている必要があります。要求したすべてのバイトを取得できない場合は、再度呼び出してさらに取得する必要があります。maximumrecv()

于 2012-10-28T21:37:35.083 に答える
1

まず、あなたが投稿したコードには論理エラーがあります:

サーバーは最初にクライアントからデータを受け取り、それに対して何かを行い、その結果をクライアントに送り返します。

反対側のクライアントもサーバーからデータを受信し、それを処理してからサーバーに送り返します。

そして、それは明らかに競合状態であり、通信を開始するために相手側にデータを送信することはありません。

その論理エラーのほかに、いくつかの C++ エラーがあります。

1)配列全体ではなく、配列からのバイトをmemset(array, 0, sizeof(array))0だけ初期化します。配列全体を0初期化したい場合(そして私はあなたがそれを望んでいると思います)は常に次のように呼び出す必要があるためです。sizeof(int*)sizeof(array)sizeof(int*)

memset(array, 0, (maximum + 1) * sizeof(int));

またはさらに良い:

std::fill( array, array + maximum + 1, 0 );

std::vectorまた、C++では、生のポインターの代わりに次のようなクラスを使用する方がはるかに優れています。

std::vector<int> array( maximum + 1 ); // automatically initialize to 0

2)配列タイプはint*であり、send/recvその入力をバイト単位でカウントするためsend/recv、配列全体を使用する場合は、次のようなものが必要です。

send(sockfd, (char*)array, maximum * sizeof(int), 0);

3) の戻り値を確認する必要がありますsend/recv。特に、各呼び出しでデータが少なくrecvなる可能性があるrecvためです。たとえば、8K データを送信し、recv最初の 1K のみを受信し、残りはネットワーク バッファーに残るため、データを読み取るまで繰り返し呼び出す必要があります。完全にバッファリングします。

于 2012-10-28T22:35:57.967 に答える