gpt4 book ai didi

c - recv() 后数组值意外更改

转载 作者:太空宇宙 更新时间:2023-11-04 05:59:12 26 4
gpt4 key购买 nike

在我运行服务器之后,我运行了两个客户端实例。现在我第一次运行客户端时,接收到的数据被保存到数组 [0] 中,但是当我运行第二个客户端时,数组 [0] 的值令人惊讶地被新值覆盖。新数据应保存在数组 [1] 中而不是覆盖。我犯了什么错误?

字符*数组[100];int 数组计数 = 0;是全局变量。

void *server()
{
int listenfd = 0;
connfd = 0;
struct sockaddr_in serv_addr;

listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(port));

if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))<0)
{
perror("bind");
exit(1);
}

listen(listenfd, 10);

while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);

printf("data in Array[0] before recv : %s\n",Array[0]);

int ns;
char revdData[2000];
bzero(revdData,2000);
ns = recv(connfd,revdData,2000,0);
close(connfd);

printf("data in Array[0] after recv : %s\n",Array[0]);

Array[ArrayCount] = revdData;
ArrayCount = ArrayCount+1;
}
}

客户端代码

void *client()
{

int soctype = SOCK_STREAM;
struct hostent *hp, *gethostbyname();
struct sockaddr_in servR;
struct servent *seR;
int tempSocket;
char *host = "localhost";

if ((tempSocket = socket(AF_INET, soctype, 0)) < 0)
{
perror("socket");
exit(1);
}

if ((hp = gethostbyname(host)) == NULL)
{
exit(1);
}

servR.sin_family = AF_INET;
memcpy(&servR.sin_addr, hp->h_addr, hp->h_length);
if (isdigit(*port))
{
servR.sin_port = htons(atoi(port));
}
else
{
if ((seR = getservbyname(port, (char *)NULL)) < (struct servent *) 0)
{
perror(port);
exit(1);
}
servR.sin_port = seR->s_port;
}


if (connect(tempSocket, (struct sockaddr *) &servR, sizeof(servR)) < 0)
{
perror("connect");
exit(1);
}

char input[100];
fgets(input,100,stdin);
int n;
n=send(tempSocket,input,100,0);
if (n < 0)
{
error("Send");
}
}

输出如下:

data in Array[0] before recv : (null)
data in Array[0] after recv : (null)
data in Array[0] before recv : 1st Instance
data in Array[0] after recv : 2nd Instance

recv 之后的理想数据应该是“第一个实例”,因为我正在打印数组 [0]。

最佳答案

服务器代码中的这个分配没有做你想做的:

Array[ArrayCount] = revdData;

这是无效代码,因为 revdData 是一个范围限定为 server() 的本地数组。赋值不复制数组,它复制指向其第一个元素的指针。因此,当您从 server() 返回时,Array 包含指向无效位置的指针 - 本地 revdData 数组的内存是无效的。接下来会发生什么是未知的。通常,由于您将再次调用 server(),很可能相同的内存空间被重新用于新的 revdData 数组,因此它最终会被覆盖你不想要的。

要修复它,您必须在 Array[ArrayCount] 中分配内存然后使用 strncpy,或者使用 strndup

以下是您可以使用 strncpy 执行的操作:

Array[ArrayCount] = malloc(ns);
strncpy(Array[ArrayCount], revdData, (size_t) ns);

此外,您可以将 nsint 更改为 ssize_t,这是 recv 的返回类型。

如果你想使用strndup,你不需要显式地使用malloc,但是,如果你的数据包含空字节,它不会复制超过那个点, 如果没有,它会在复制的字符串中添加一个空字节,这可能不是您想要的。

注意这种方式引入了内存管理的问题;在某些时候,您必须释放分配给 Array 中每个位置的内存。您有责任这样做,尽管在小程序中您通常可以依赖这样一个事实:所有分配的内存在程序终止时由操作系统释放。

关于c - recv() 后数组值意外更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21929584/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com