send()和recv()套接字参数

时间:2012-10-28 21:32:57

标签: c++ sockets

我的程序发生了一些奇怪的事情,我不确定我应该做什么。这是我的代码到目前为止的伪代码版本:

服务器:

//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个参数(当前设置为最大值)时,我的程序行为也不同。如果用户输入的最大值为100,那么它实际上可以正常工作,但除此之外的任何东西都会将其搞砸。

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

2 个答案:

答案 0 :(得分:1)

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

mathFunction(array);

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

答案 1 :(得分:1)

首先,您发布的代码存在逻辑错误:

服务器首先从客户端接收数据,对其执行某些操作,然后将其结果发送回客户端。

另一方面,客户端也从服务器接收数据,对其执行某些操作,然后将其发送回服务器。

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

除了那个逻辑错误,你还有一些C ++错误:

1)memset(array, 0, sizeof(array))只有0来自你的数组而不是整个数组初始化sizeof(int*)字节,因为sizeof(array)总是sizeof(int*)如果你想初始化整个数组(和我你想要它吗?你应该打电话给:

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,其余部分保留在网络缓冲区中,因此您应该反复调用它,直到您完全读取缓冲区为止。