我的程序发生了一些奇怪的事情,我不确定我应该做什么。这是我的代码到目前为止的伪代码版本:
服务器:
//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,那么它实际上可以正常工作,但除此之外的任何东西都会将其搞砸。
我知道这是一个很长的镜头,但任何人都可以看到我做错了吗?
答案 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,其余部分保留在网络缓冲区中,因此您应该反复调用它,直到您完全读取缓冲区为止。