C并发UDP套接字,奇怪的分段错误

我要么非常疲倦而且没有注意到一些简单的事情,或者这完全是在与我联系。 我遇到了一个分段错误(核心转储),我已经设法将它精确定位到worker函数中的sendto()。 (在服务器中)

服务器代码:

//UDPServer.c /* * gcc -o server UDPServer.c * ./server   */ #include  #include  #include  #include  #include  #include  #include  #include  void err(char *str) { perror(str); exit(1); } int sock; typedef struct { struct sockaddr_in client; int buffsize; char *msg; } data; void *worker (void* asd) { int len; FILE *fp; data d; d = *(data*) asd; char buff[d.buffsize]; printf("Received packet from %s:%d\nData:%sSize:%d\n", inet_ntoa(d.client.sin_addr), ntohs(d.client.sin_port) ,d.msg,d.buffsize); char * fn; memcpy (fn,d.msg,strlen(d.msg)-1); fp = fopen(fn,"rb"); int bytes; len = sizeof(d.client); printf ("%d\n",len); while (bytes=fread(buff,sizeof(char),d.buffsize,fp)) { printf ("Server sent %d bytes.\n",bytes); -> this if right here. this causes the core dump when attempting to send if(sendto(sock , &buff , sizeof(buff),0,(struct sockaddr *)&d.client,len)<0) err("Error sending."); } fclose(fp); } int main(int argc, char** argv) { struct sockaddr_in server, client; int port, i; socklen_t slen=sizeof(client); if(argc != 3) { printf("Usage:  \n"); exit(0); } else sscanf(argv[1],"%d",&port); int buffsize = atoi(argv[2]); char buff[buffsize]; if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) err("socket"); else printf("Server : Socket() successful\n"); bzero(&server, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sock, (struct sockaddr* ) &server, sizeof(server))==-1) err("bind"); else printf("Server : bind() successful\n"); while(1) { memset(&buff,0,sizeof(buff)); if (recvfrom(sock, &buff, sizeof(buff), 0, (struct sockaddr*)&client, &slen)==-1) err("recvfrom()"); data d; d.client = client; d.buffsize = buffsize; d.msg = buff; pthread_t t; pthread_create(&t,NULL,worker,&d); pthread_join(t,NULL); } return 0; } 

我不认为客户端在这里是相关的,因为它的唯一工作就是发送文件名。 阅读工作顺便说一句,我已经测试过了。

无论如何,我只是想暂时发送文件的内容。我一直试图在过去一小时内解决这个问题,而对于我的生活,我无法找出它的问题。 分段错误对我没有意义。

任何建议都非常感谢。

我对sendto中的sizeof(buff )感到紧张。 buff的大小根据参数在运行时固定。 sizeof是一个编译时操作。 (或者至少它回到过去的好时光 – 我不确定C99)哦,没关系 – 我看到这已经改变了

不过,为什么不在那里使用d.buffsize呢? 或者也许是bytes ,因为您可能没有填充缓冲区。

虽然@ 21Zoo在C99中的动态数组是错误的,但我认为他找到了根本问题

 char * fn; memcpy (fn,d.msg,strlen(d.msg)-1); 

fn没有分配要复制到的内存,因此您正在写入内存中的随机点。 sendto某些内容可能会绊倒现在包含垃圾的内存。

您需要malloc(strlen(d.msg)+1)或使用strdup代替。