-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 函数的第三个参数(当前设置为maximum)时,我的程序的行为不同。如果用户输入最多 100 个,它实际上会完美运行,但除此之外的任何东西都搞砸了。

我知道这是一个很长的镜头,但是任何人都可以看到我做错了什么吗?

4

2 回答 2

1

似乎显然不正确的一件事是:

mathFunction(array);

不告诉mathFunction()数组中有多少元素。实际上,当您调用时,您通过不在任何地方存储它来丢弃此信息recv()(您的代码所做的只是检查它是否小于零,但如果它是正数则不使用它)。调用时recv(),您的代码必须准备好接收从 1 到的任意数量的字节maximum。如果你没有得到你要求的所有字节,那么你需要recv()再次调用以获得更多。

于 2012-10-28T21:37:35.083 回答
1

首先,您发布的代码有一个逻辑错误:

服务器首先从客户端接收数据,对其进行处理,然后将其结果发送回客户端。

在另一端,客户端也从服务器接收数据,对其进行处理,然后将其发送回服务器。

这显然是一种竞争条件,没有人向另一方发送数据以开始通信。

除了逻辑错误之外,您还有一些 C++ 错误:

1)memset(array, 0, sizeof(array))只有 0 初始化sizeof(int*)数组中的字节而不是整个数组,因为sizeof(array)如果sizeof(int*)你想 0 初始化整个数组(我认为你想要它),你应该调用:

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

甚至更好:

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

在 C++ 中,使用类std::vector代替原始指针要好得多:

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 回答