0

私は過去5時間コードを注ぎ込み、どこにも行き着きませんでした。コードを実行するたびに、セグメンテーション違反が発生します。クライアント側で発生することもあれば、サーバー側で発生することもあるので、何が起こっているのかわかりません。 このコードは、100までの素数を検索しようとすると機能しますが、それ以降は機能しません。私が最後にここに投稿したとき、私は完全なコードを投稿するように言われたので、ここにあります:

サーバ:

void sieve(int *isComposite, int maximum, int maxSqrt) {

    int m = isComposite[0];
    int currentPrime = m-1;

    //Loop through "maxSqrt" times through the array
    if(m <= maxSqrt){
        //Loop through the multiples of the number we're
        //looking at (m) and mark them as composite (1)
        for (int k = currentPrime * currentPrime; k <= maximum; k += currentPrime){
            if(isComposite[k+1] == 0){
                //cout << "Removing: " << k << endl;
                isComposite[k+1] = 1;
            }
        }
    }
}

int main(int argc, char *argv[]){
    int sockfd, newsockfd, portno; // listen on sock_fd, new connection on new_fd, port number
    socklen_t clilen;

    struct sockaddr_in serv_addr, cli_addr;  // my address information, connector's address information
    int n;
    int open = 1; //true


    if (argc < 2) {
        fprintf(stderr,"ERROR, no port provided\n");
        exit(1);
    }

    //Socket setup
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        error("ERROR opening socket");
    } 
    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);             //port number (ex. 10.12.110.57 or thing-1.uwec.edu)
    serv_addr.sin_family = AF_INET;     // host byte order
    serv_addr.sin_port = htons(portno); // short, network byte order
    serv_addr.sin_addr.s_addr = INADDR_ANY;  // use my IP address

    //Bind socket
    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        error("ERROR on binding");
    }
    //Listen for connection
    listen(sockfd,5);

    //Accept the connection
    clilen = sizeof(cli_addr);
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
    if (newsockfd < 0){
        error("ERROR on accept");
    }
    printf("Connection accepted!\n");

    // Variable to college the largest number in the range
    int maximum;

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

    int *maxToSend = new int[1];
    maxToSend[0] = maximum;

    if(send(newsockfd, maxToSend, 10, 0) < 0){
        perror("ERROR sending to socket");
    }


    int maxSqrt = (int)sqrt((double)maximum);

    // Declare the array to hold important 
    // information and the numbers to sieve
    int *isComposite= new int[maximum+1]();

    // Insert the variable that keeps track of where we
    // are in the array, starting with 2 (the first prime)
    // which is held in isComposite[3]
    isComposite[0] = 3;

    // Run the sieve for each prime we come accross
    // until we reach the prime that is the square
    // root of the maximum (isComposite[2])
    while(isComposite[0] <= maxSqrt){

        // Unless it is the first time through
        // Receive from the client
        if(isComposite[0] > 3){
            if(recv(newsockfd, isComposite, (maximum+1)* sizeof(int), 0) < 0){
                perror("ERROR receiving from socket");
            }
        }

        // If we're not done:
        if(isComposite[0] <= maxSqrt){
            // Sieve the range
            sieve(isComposite, maximum, maxSqrt);
            isComposite[0]++;

            // Find the next prime
            while(isComposite[isComposite[0]] == 1){
                isComposite[0]++;
            }
            cout << "Doing next Sieve on: " << isComposite[0]-1 << endl;

        }

        // If we're still not done:
        if(send(newsockfd, isComposite, (maximum+1)* sizeof(int), 0) < 0){
            if(send(newsockfd, isComposite, maximum+1500, 0) < 0){
                perror("ERROR sending to socket");
            }
        }
    }
    return 0;
}

クライアント:

void sieve(int *isComposite, int maximum, int maxSqrt) {

    int m = isComposite[0];
    int currentPrime = m-1;

    //Loop through "maxSqrt" times through the array
    if(m <= maxSqrt){
        //Loop through the multiples of the number we're
        //looking at (m) and mark them as composite (1)
        for (int k = currentPrime * currentPrime; k <= maximum; k += currentPrime){
            if(isComposite[k+1] == 0){
                //cout << "Removing: " << k << endl;
                isComposite[k+1] = 1;
            }
        }
    }
}

int main(int argc, char *argv[]){

    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    int open = 1; //true
    char c = 'a';

    if (argc < 3) {
       fprintf(stderr,"usage %s hostname port\n", argv[0]);
       exit(0);
    }

    portno = atoi(argv[2]);  //parse port number

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        error("ERROR opening socket");
    }

    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;   // host byte order
    bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr, server->h_length);
    serv_addr.sin_port = htons(portno);  // short, network byte order


    if (connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        error("ERROR connecting");
    }

    int *maxToSend = new int[1];

    if(recv(sockfd, maxToSend, 10, 0) < 0){
        perror("ERROR receiving from socket");
    }

    int maximum = maxToSend[0];
    int maxSqrt = (int)sqrt((double)maximum);

    int *isComposite= new int[maximum+1]();

    while(isComposite[0] <= maxSqrt){

        if(recv(sockfd, isComposite, (maximum+1)* sizeof(int), 0) < 0){
            perror("ERROR receiving from socket");
        }

        // Sieve the range
        sieve(isComposite, maximum, maxSqrt);
        isComposite[0]++;

        // Find the next prime
        while(isComposite[isComposite[0]] == 1){
            isComposite[0]++;
        }
        cout << "Doing next Sieve on: " << isComposite[0]-1 << endl;

        if(send(sockfd, isComposite, (maximum+1)* sizeof(int), 0) < 0){
            perror("ERROR sending to socket");
        }

    }

    close(sockfd);
    return(0);
}
4

1 に答える 1

3

その理由は、ふるいのサイズが1つのパケットが保持できるサイズよりも大きくなっているためです。1つのパケットに格納できるのは約1400バイトのみであり、送信および受信機能はこれを考慮していません。送信しようとしているすべてのデータを送信するか、読み取ろうとしているすべてのデータを読み込むまで、ループする必要があります。でこれを実行しようとしたようですがsend(newsockfd, isComposite, maximum+1500, 0)、ループでこれを実行し、の戻り値から送信したデータの量を追跡する必要がありますsend

単純な関数は次のようになります

bool sendAll(int socket, const void *data, ssize_t size) {
    ssize_t sent = 0;
    ssize_t just_sent;
    while (sent < size) {
        just_sent = send(socket, data + sent, size - sent, 0);
        if (just_set < 0) {
            return false;
        }
        sent += just_sent;
    }
    return true;
}

そして、に似たものrecv

于 2012-10-29T00:46:07.937 に答える