gpt4 book ai didi

c - UDP 套接字超时循环的内存错误

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

我正在编写一个 UDP 发送/接收函数,当它在一定时间内没有得到回复时会超时,并会重新发送数据包。我正在使用 socksetopt 设置超时,这一切似乎都有效,直到我进行最后一次迭代,然后出现大量错误消息。

我的代码在这里:

int itermax=10;
int itercount=0;

int send_and_receive(void* message, void* reply, int do_send, int expect_reply){
struct sockaddr_in serv_addr;
int sockfd, i, slen=sizeof(serv_addr);
int buflen = BUFLEN;
void* buf = NULL;
struct timeval tv;
int n_timeouts=1;
int retval;

printf("N = %d\n", itercount);
itercount++;

if ( (strlen(message)) >= BUFLEN)
err("Message too big");

buf = malloc(buflen);

if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
err("socket");

tv.tv_sec = 1;
tv.tv_usec = 0;
if( setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0 ){
err("Setting Timout");
}

bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_aton(IP_ADDRESS, &serv_addr.sin_addr)==0)
err("inet_aton() failed\n");

if(do_send == TRUE){
strcpy(buf, message);
if (sendto(sockfd, buf, buflen, 0, (struct sockaddr*)&serv_addr, slen)==-1)
err("sendto()");
}

if (expect_reply == TRUE){
if( recvfrom(sockfd, buf, buflen, 0, (struct sockaddr*)&serv_addr, &slen) == -1){

close(sockfd);
free(buf);
if(itercount < itermax){
send_and_receive(message, reply, do_send, expect_reply);
}
else{
perror("recvfrom");
return -1;
}
}
}

memcpy(reply, buf, BUFLEN);
close(sockfd);
free(buf);
return 0;
}

错误信息:


recvfrom: Resource temporarily unavailable
*** glibc detected *** : double free or corruption (top): 0x083af008 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6e341)[0xa8a341]
/lib/tls/i686/cmov/libc.so.6(+0x6fb98)[0xa8bb98]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xa8ec7d]
[0x8048a44]
[0x80489ff]
[0x80489ff]
[0x80489ff]
[0x80489ff]
[0x80489ff]
[0x80489ff]
[0x80489ff]
[0x80489ff]
[0x8048a84]
[0x8048c35]
[0xac000000]
======= Memory map: ========
00173000-00174000 r-xp 00000000 00:00 0 [vdso]
008a6000-008c3000 r-xp 00000000 08:01 2224682 /lib/libgcc_s.so.1
008c3000-008c4000 r--p 0001c000 08:01 2224682 /lib/libgcc_s.so.1
008c4000-008c5000 rw-p 0001d000 08:01 2224682 /lib/libgcc_s.so.1
00a1c000-00b75000 r-xp 00000000 08:01 2362849 /lib/tls/i686/cmov/libc-2.11.1.so
00b75000-00b77000 r--p 00159000 08:01 2362849 /lib/tls/i686/cmov/libc-2.11.1.so
00b77000-00b78000 rw-p 0015b000 08:01 2362849 /lib/tls/i686/cmov/libc-2.11.1.so
00b78000-00b7b000 rw-p 00000000 00:00 0
00b84000-00b9f000 r-xp 00000000 08:01 2230784 /lib/ld-2.11.1.so
00b9f000-00ba0000 r--p 0001a000 08:01 2230784 /lib/ld-2.11.1.so
00ba0000-00ba1000 rw-p 0001b000 08:01 2230784 /lib/ld-2.11.1.so
08048000-08049000 r-xp 00000000 08:01 667121 /home/james/BitBucket/rtig/Code/c
08049000-0804a000 r--p 00000000 08:01 667121 /home/james/BitBucket/rtig/Code/c
0804a000-0804b000 rw-p 00001000 08:01 667121 /home/james/BitBucket/rtig/Code/c
083af000-083d0000 rw-p 00000000 00:00 0 [heap]
b7600000-b7621000 rw-p 00000000 00:00 0
b7621000-b7700000 ---p 00000000 00:00 0
b7732000-b7733000 rw-p 00000000 00:00 0
b7745000-b7748000 rw-p 00000000 00:00 0
bfc70000-bfc85000 rw-p 00000000 00:00 0 [stack]
Aborted

如有任何帮助,我们将不胜感激。

最佳答案

由于您释放了此处的缓冲区,因此发生了双重释放:

if( recvfrom(sockfd, buf, buflen, 0, (struct sockaddr*)&serv_addr, &slen) == -1){
close(sockfd);
free(buf);

然后当您退出该函数时:

memcpy(reply, buf, BUFLEN);
close(sockfd);
free(buf);
return 0;

要解决这个问题,释放 buf 后,将指针设置为 NULL:

if( recvfrom(sockfd, buf, buflen, 0, (struct sockaddr*)&serv_addr, &slen) == -1){
close(sockfd);
free(buf);
buf = NULL;

还有一个问题是,您可能会在 buf 被释放后读取它。 (注意上面的 memcpy。)

关于c - UDP 套接字超时循环的内存错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18896986/

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