C并发UDP套接字,奇怪的分段错误 [英] C concurrent UDP socket , weird segmentation fault

查看:32
本文介绍了C并发UDP套接字,奇怪的分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要么很累,没有注意到一些简单的事情,要么这完全搞砸了.我遇到了分段错误(核心转储),并且我设法将其定位到工作函数中的 sendto().(在服务器中)

I'm either very tired and not noticing something simple , or this is completely screwing with me. I'm getting a segmentation fault ( core dumped ) and I've managed to pinpoint it to the sendto() in the worker function. (in the server)

服务器代码:

    //UDPServer.c

/* 
 *  gcc -o server UDPServer.c
 *  ./server <port> <buffersize>
 */
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h> 
#include <string.h>


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: <Port> <Bytes>\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;
}

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

I don't think the client is relevant here since it's only job is to send the filename. The read works btw , I've tested.

无论如何,我暂时只是想发送文件的内容.过去一个小时我一直在努力解决这个问题,我一生都找不到问题所在.分段错误对我来说毫无意义.

Anyway , I'm just trying to send the content of the file for the moment.I've been trying to figure this out for the past hour and for the life of me I can't find out what's it's problem. The segmentation fault makes no sense to me.

非常感谢任何建议.

推荐答案

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

I'd be nervous about the sizeof(buff) in the sendto. buff's size is fixed at runtime based on the argument. But sizeof is a compile-time operation. (Or at least it was back in the good old days - I'm not sure about C99) Oh, nevermind - I see that has changed

不过,为什么不使用 d.buffsize 代替呢?或者可能是 bytes,因为您可能没有填充缓冲区.

Still, why not use d.buffsize there instead? Or maybe bytes, since you might not have filled the buffer.

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

Although @21Zoo is wrong about dynamic arrays in C99, I think he found the root problem

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

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

fn has no memory allocated to copy into, so you are writing to a random point in memory. Something in the sendto is probably stumbling over that memory which now contains garbage.

您要么需要malloc(strlen(d.msg)+1),要么改用strdup.

You either need to malloc(strlen(d.msg)+1) or use strdup instead.

这篇关于C并发UDP套接字,奇怪的分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆