【问题标题】:C : error while writing file using UDP socketC:使用UDP套接字写入文件时出错
【发布时间】:2015-08-27 16:02:17
【问题描述】:

我必须通过 UDP 1024 字节的文件(在本例中为 txt 文件)发送到服务器并将此字节写入输出文件。我收到此错误:

write(): bad address

我需要通过数据结构传递字节,因此创建了一个名为“pkt”的结构,并带有void *buf,我可以在其中写入字节。 这是我的示例程序。

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SERV_PORT           5197
#define MAX_BLOCK_SIZE      1024

struct pkt {
    void *buf;
    int num;
};

int main(int argc, char *argv[]) {

    if (argc != 3) {
        fprintf(stderr, "Usage: %s <IP SERVER> <file>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int sockfd;
    struct sockaddr_in addr;
    int fd;

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd < 0)
    {
        perror("socket()");
        exit(EXIT_FAILURE);
    }

    memset((void*)&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(SERV_PORT);

    if (inet_pton(AF_INET, argv[1], &addr.sin_addr) <= 0)
    {
        perror("inet_pton()");
        exit(EXIT_FAILURE);
    }

    fd = open(argv[2], O_RDONLY);
    if(fd == -1)
    {
        perror("open()");
        exit(EXIT_FAILURE);
    }
    //READ FILE
    ssize_t n;
    void *buf;

    buf = alloca(MAX_BLOCK_SIZE);
    n = read(fd, buf, MAX_BLOCK_SIZE);
    if(n != MAX_BLOCK_SIZE)
    {
        perror("read()");
        exit(EXIT_FAILURE);
    }

    struct pkt packet;
    packet.buf = buf;
    packet.num = 0;

    if(sendto(sockfd, &packet, sizeof(struct pkt), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0)
    {
        perror("sendto()");
        exit(EXIT_FAILURE);
    }

    close(fd);

    return EXIT_SUCCESS;

}

服务器端:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SERV_PORT           5197
#define MAX_BLOCK_SIZE      1024

struct pkt {
    void *buf;
    int num;
};

int main() {
    int sockfd;
    struct sockaddr_in addr;
    socklen_t len;
    int output;

    output = open("test.txt", O_WRONLY|O_CREAT, 0664);
    if(output == -1)
    {
        perror("open()");
        exit(EXIT_FAILURE);
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd < 0)
    {
        perror("socket()");
        exit(EXIT_FAILURE);
    }

    memset((void*)&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(SERV_PORT);

    if(bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
    {
        perror("bind()");
        exit(EXIT_FAILURE);
    }

    while (1) {
        len = sizeof(addr);
        ssize_t n;

        struct pkt packet;
        n = recvfrom(sockfd, &packet, sizeof(struct pkt), 0, (struct sockaddr*)&addr, &len);
        if( n < 0)
        {
            perror("recvfrom()");
            exit(EXIT_FAILURE);
        }

        printf("Packet number %d\n", packet.num);

        void *buf = (packet.buf);

        if (write(output, buf, MAX_BLOCK_SIZE) == -1) {
            perror("write()");
            exit(EXIT_FAILURE);

        }
    }

    return 0;
}

【问题讨论】:

  • 你期望sizeof(struct pkt) 会返回什么?
  • 我的pkt数据结构的大小
  • 您希望您的“packet.buf”在收到后有什么含义吗?
  • @Simon 你认为该结构的大小是多少???为什么不直接使用原始缓冲区来读取数据?
  • “ packet.buf ”必须包含我要写入的字节。由客户填写。

标签: c file sockets udp fwrite


【解决方案1】:

这一行:

packet.buf = buf;

是代码的主要问题。

这一行所做的只是复制一个指向 buf 的指针。

所以当 sendto() 执行时,发送的是指针,而不是 buf 的内容。

建议:

替换:

struct pkt {
    void *buf;
    int num;
};

struct pkt {
    char buf[1024];
    int num;
};

并替换它:

packet.buf = buf;

memcpy( packet.buf, buf, sizeof( packet.buf ) );

【讨论】:

  • 谢谢,它有效。但如果我需要发送 jpg、pdf 或其他文件...我可以使用“char”缓冲区发送它吗?
猜你喜欢
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多