Практически завершенный! C ++ простое число сито над сокетами

Я полил свой код за последние 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; //trueif (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 orderif (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);
}

0

Решение

Причина в том, что размер вашего сита становится больше, чем может вместить один пакет. Вы можете хранить только около 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,

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]