Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C sendto发送数据包时创建分段错误_C_Udp_Sendto - Fatal编程技术网

C sendto发送数据包时创建分段错误

C sendto发送数据包时创建分段错误,c,udp,sendto,C,Udp,Sendto,我正试图通过UDP发送数据包,但我在第198行遇到seg故障: sendto(socketfd, buffer_str, total_len, 0, res->ai_addr, res->ai_addrlen); 我不太确定是什么原因造成的。我已经通过GDB运行了这个程序,所有参数似乎都没有任何错误。我试图发送的文件只是一个简单的txt文件,其中包含文本“Lorem ipsum dolor sit amet” 第76行的第一个sendto运行得非常好,第78行的recv也是如此。

我正试图通过UDP发送数据包,但我在第198行遇到seg故障:

sendto(socketfd, buffer_str, total_len, 0, res->ai_addr, res->ai_addrlen);

我不太确定是什么原因造成的。我已经通过GDB运行了这个程序,所有参数似乎都没有任何错误。我试图发送的文件只是一个简单的txt文件,其中包含文本“Lorem ipsum dolor sit amet”

第76行的第一个sendto运行得非常好,第78行的recv也是如此。当我尝试用like 76的代码替换198上的sendto时,我得到了相同的错误

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netinet/in.h>
#include <netdb.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>

struct packet {
    unsigned int total_frag;
    unsigned int frag_no;
    unsigned int size;
    char* filename;
    char filedata[1000];
};

struct node {
    struct node* next;
    struct packet data;
};

struct list {
    struct node* head;
};

int main(int argc, char *argv[]) {
    printf("ftp <file name>\n");
    
    struct sockaddr_storage their_addr;
    socklen_t addr_size = sizeof(their_addr);
    struct addrinfo hints, *res;
    char* port = "5050";//argv[2];
    struct sockaddr_in *serverAddr;
    serverAddr = malloc(sizeof(struct sockaddr_in));
    memset(&hints, 0, sizeof(hints));
    memset(serverAddr, 0, sizeof(*serverAddr));
    serverAddr->sin_family = AF_INET;
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_addr = (struct sockaddr *) serverAddr;

    getaddrinfo("ug168.eecg.utoronto.ca"/*argv[1]*/, port, &hints, &res);
    int socketfd = socket(PF_INET, SOCK_DGRAM, 0);
    char fileName[100];
    scanf("%s", fileName);
    int fd = open(fileName, O_RDWR);
    if(fd == -1) {
        return 0;
    }

    struct timeval pre_time, post_time;
    gettimeofday(&pre_time, NULL);
    sendto(socketfd, (char*)"ftp", 3, 0, res->ai_addr, res->ai_addrlen);
    char buf[1000];
    int length = recvfrom(socketfd, buf, 1000, 0, (struct sockaddr *)&serverAddr, &addr_size);
    gettimeofday(&post_time, NULL);

    buf[length] = '\0';
    if(strcmp("yes", buf) == 0) {
        printf("A file transfer can start\n");
    }
    printf("seconds : %ld\nmicro seconds : %ld\n", post_time.tv_sec - pre_time.tv_sec, post_time.tv_usec - pre_time.tv_usec);

    FILE *file;
    file = fopen(fileName, "rb"); //rb = read as binary
    fseek(file, 0, SEEK_END);
    int fileLength = ftell(file);
    fseek(file, 0, SEEK_SET);

    char buffer[fileLength];
    fread(buffer, fileLength, 1, file);
    fclose(file);
    int frag_total = fileLength / 1000;
    if(fileLength % 1000 != 0) {
        frag_total++;
    }

    struct list packet_list;
    packet_list.head = malloc(sizeof(struct node));
    struct node* curr = packet_list.head;
    for(int i = 0; i < frag_total; i++) {
        curr->data.total_frag = frag_total;
        curr->data.frag_no = i + 1;
        if(i == frag_total - 1) {
            curr->data.size = fileLength % 1000;
        } else {
            curr->data.size = 1000;
        }
        curr->data.filename = malloc(sizeof(char) * (strlen(fileName) + 1));
        strcpy(curr->data.filename, fileName);
        if(i == frag_total - 1) {
            //copy data equal to remainder
            for(int j = 0; j < fileLength % 1000; j++) {
                curr->data.filedata[j] = buffer[1000 * i + j];
            }
        } else {
            //copy 1000 bytes
            for(int j = 0; j < 1000; j++) {
                curr->data.filedata[j] = buffer[1000 * i + j];
            }
        }
        if(i < frag_total - 1) {
            curr->next = malloc(sizeof(struct node));
            curr = curr->next;
        }
    }

    curr = packet_list.head;
    while(curr != NULL) {
        int j = curr->data.total_frag;
        int frag_total_len = 0;
        while(j != 0) {
            j /= 10;
            frag_total_len++;
        }
        j = curr->data.frag_no;
        int frag_no_len = 0;
        while(j != 0) {
            j /= 10;
            frag_no_len++;
        }
        j = curr->data.size;
        int size_len = 0;
        while(j != 0) {
            j /= 10;
            size_len++;
        }
        int name_len = strlen(curr->data.filename);

        int total_len = frag_total_len + frag_no_len + size_len + name_len + 4 + curr->data.size; //4 bc 4 colons

        char buffer_str[total_len];
        j = 0;

        char strbuf[total_len];

        sprintf(strbuf, "%d", curr->data.total_frag);
        for(int k = j; k < j + frag_total_len; k++) {
           buffer_str[k] = strbuf[k-j];
        }
        j += frag_total_len;
        buffer_str[j] = ':';
        j++;

        sprintf(strbuf, "%d", curr->data.frag_no);
        for(int k = j; k < j + frag_no_len; k++) {
           buffer_str[k] = strbuf[k-j];
        }
        j += frag_no_len;
        buffer_str[j] = ':';
        j++;

        sprintf(strbuf, "%d", curr->data.size);
        for(int k = j; k < j + size_len; k++) {
           buffer_str[k] = strbuf[k-j];
        }
        j += size_len;
        buffer_str[j] = ':';
        j++;

        for(int k = 0 ; k < name_len; k++, j++) {
            buffer_str[j] = curr->data.filename[k];
        }

        buffer_str[j] = ':';
        j++;
        for(int k = 0; k < curr->data.size; k++, j++) {
            buffer_str[j] = curr->data.filedata[k];
        }

        sendto(socketfd, buffer_str, total_len, 0, res->ai_addr, res->ai_addrlen);
        curr = curr->next;
    }
    return 0;
}

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构包{
无符号整数合计;
无符号整数框架编号;
无符号整数大小;
字符*文件名;
char filedata[1000];
};
结构节点{
结构节点*下一步;
结构包数据;
};
结构列表{
结构节点*头部;
};
int main(int argc,char*argv[]){
printf(“ftp\n”);
结构sockaddr\u存储它们的地址;
socklen\u t addr\u size=sizeof(他们的地址);
结构addrinfo提示,*res;
char*port=“5050”//argv[2];
*服务器地址中的结构sockaddr_;
serverAddr=malloc(sizeof(struct sockaddr_in));
memset(&hints,0,sizeof(hints));
memset(serverAddr,0,sizeof(*serverAddr));
serverAddr->sin_family=AF_INET;
hits.ai_family=AF_INET;
hits.ai_socktype=SOCK_DGRAM;
hipts.ai_addr=(struct sockaddr*)serverAddr;
getaddrinfo(“ug168.eecg.utoronto.ca”/*argv[1]*/,端口和提示,&res);
int socketfd=插座(PF INET,SOCK DGRAM,0);
字符文件名[100];
scanf(“%s”,文件名);
int fd=打开(文件名,O_RDWR);
如果(fd==-1){
返回0;
}
struct timeval pre_time、post_time;
gettimeofday(&pre_time,NULL);
sendto(socketfd,(char*)“ftp”,3,0,res->ai_addr,res->ai_addrlen);
char-buf[1000];
int length=recvfrom(socketfd,buf,1000,0,(struct sockaddr*)和serverAddr,&addr\u size);
gettimeofday(&post_time,NULL);
buf[length]='\0';
如果(strcmp(“是”,buf)==0){
printf(“可以开始文件传输\n”);
}
printf(“秒数:%ld\n微秒数:%ld\n”,post_time.tv_sec-pre_time.tv_sec,post_time.tv_usec-pre_time.tv_usec);
文件*文件;
file=fopen(文件名,“rb”);//rb=读取为二进制
fseek(文件,0,SEEK_END);
int fileLength=ftell(文件);
fseek(文件,0,搜索集);
字符缓冲区[文件长度];
fread(缓冲区,文件长度,1,文件);
fclose(文件);
int frag_total=文件长度/1000;
如果(文件长度%1000!=0){
frag_total++;
}
结构列表数据包列表;
packet_list.head=malloc(sizeof(struct node));
结构节点*curr=packet\u list.head;
对于(int i=0;idata.total\u frag=frag\u total;
curr->data.frag\u no=i+1;
如果(i==frag_总计-1){
curr->data.size=文件长度%1000;
}否则{
curr->data.size=1000;
}
curr->data.filename=malloc(sizeof(char)*(strlen(filename)+1);
strcpy(curr->data.filename,filename);
如果(i==frag_总计-1){
//复制与余数相等的数据
对于(int j=0;jdata.filedata[j]=缓冲区[1000*i+j];
}
}否则{
//复制1000字节
对于(int j=0;j<1000;j++){
curr->data.filedata[j]=缓冲区[1000*i+j];
}
}
如果(inext=malloc(sizeof(结构节点));
当前=当前->下一步;
}
}
curr=数据包\列表头;
while(curr!=NULL){
int j=当前->数据.total\u frag;
整数帧总长度=0;
而(j!=0){
j/=10;
frag_total_len++;
}
j=当前->数据.frag\u编号;
int frag_no_len=0;
而(j!=0){
j/=10;
frag_no_len++;
}
j=当前->数据.size;
int size_len=0;
而(j!=0){
j/=10;
大小_len++;
}
int name\u len=strlen(curr->data.filename);
int total\u len=frag\u total\u len+frag\u no\u len+size\u len+name\u len+4+curr->data.size;//4 bc 4冒号
字符缓冲区长度[总长度];
j=0;
char strbuf[总长度];
sprintf(strbuf,“%d”,curr->data.total\u frag);
对于(int k=j;kdata.frag_no);
对于(int k=j;kdata.size);
对于(int k=j;kdata.filename[k];
}
缓冲区_str[j]=':';
j++;
对于(int k=0;kdata.size;k++,j++){
buffer_str[j]=curr->data.filedata[k];
}
发送(socketfd,buffer_str,total_len,0,res->ai_addr,res->ai_addren);
当前=当前->下一步;
}
返回0;
}

我真的不确定是什么原因导致了这一点

原始发布的代码忽略了对
getaddrinfo()
的错误检查,它返回了一个错误代码,并且保持了
res
不变;这导致调用
sendto()
时取消对未初始化指针的引用;修订示例:

int rv = getaddrinfo("ug168.eecg.utoronto.ca"/*argv[1]*/, port, &hints, &res);
if (rv) {
    fprintf(stderr, "getaddrinfo error, rv %d\n", rv);
    return (1);
}

调用会覆盖局部变量
res

int length = recvfrom(socketfd, buf, 1000, 0, (struct sockaddr *)&serverAddr, &addr_size);
这是因为传递的是指针
serverAddr
的地址,而不是
int length = recvfrom(socketfd, buf, 1000, 0, (struct sockaddr *)serverAddr, &addr_size);