2015-08-27 23 views
1

我必須通過UDP 1024字節的文件(本例中爲txt文件)發送到服務器,並將這些字節寫入輸出文件。我收到此錯誤:C:使用UDP套接字寫文件時出錯

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; 
} 
+0

你期望'sizeof(struct pkt)'返回什麼結果? – mathematician1975

+0

我的'pkt'數據結構的大小 – Simon

+0

你希望你的'packet.buf'是什麼意思? –

回答

2

這一行:

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)); 
+0

謝謝,它的工作原理。但是,如果我需要發送一個JPG,或PDF,或另一個文件...我可以使用「char」緩衝區發送它? – Simon