2009-05-28 35 views
2

我发现了一个很好的抽象,我可以使用FILE从UDP读取数据。这对于读取数据非常有用,但是我无法通过UDP来传递数据。下面是在文件流的UDP数据读取的代码为:使用FILE流在c中读取/写入套接字

u_int8 *buf; 
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
struct sockaddr_in serverAddr; 
if (sockfd < 0) { 
    printf("Could not open socket\n"); 
    exit(1); 
} 
buf = malloc(BUF_SIZE * sizeof(u_int8)); 
serverAddr.sin_family = AF_INET; 
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); 
serverAddr.sin_port = htons(port); 
int rc = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); 
if (rc<0) { 
    printf("Could not bind to port %d\n", port); 
    exit(1); 
} 
/* Make sockfd blocking */ 
int flags = fcntl(sockfd, F_GETFL, 0); 
fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK); 

FILE *sockfile; 
sockfile = (FILE*)fdopen(sockfd, "r"); 

现在一些其他的代码可以调用:

fread(data, sizeof(u_int8), frame_payload_size, sockfile); 

这工作得很好。但是,反过来似乎并不:

u_int8 *buf; 
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
struct sockaddr_in clientAddr; 
if (sockfd < 0) { 
    printf("Could not open socket\n"); 
    exit(1); 
} 
memset((char *)&clientAddr, 0, sizeof(clientAddr)); 
buf = malloc(BUF_SIZE * sizeof(u_int8)); 
clientAddr.sin_family = AF_INET; 
clientAddr.sin_port = htons(port); 
if (inet_aton("127.0.0.1", &clientAddr.sin_addr)==0) { 
    printf("inet_aton()\n"); 
    abort(); 
} 
int rc = bind(sockfd, (struct sockaddr *)&clientAddr, sizeof(clientAddr)); 
FILE *sockfile; 
sockfile = (FILE*)fdopen(sockfd, "w"); 

一些其他的代码调用:

written = fwrite(fm->frame, sizeof(u_int8), fm->frame_length, data_out_stream); 

“写”将返回写入元素的正数,但没有UDP数据包似乎产生。

正在尝试做什么?任何建议,为什么它可能不工作?

回答

1

刷新FILE。只有在网络数据包已满或者强制刷新时才会生成网络数据包。因此,除非您写入超过1500个字节(默认值,包括标题字段),否则计算机将等待交付。

1

你没有隐藏信息,这可能很酷,但是你给了另一段代码的错误信息,也就是说你的套接字的行为就像一个流。我认为你应该坚持读/写呼叫,否则你会发现自己有一个leaky abstraction

1

这其实很奇怪。使用fflush(),或者更好一些,使用send()而不是fwrite()并且丢弃FILE。由于FILE对象如何缓冲的语义以及数据报如何保证不按顺序到达/到达,您将遇到意外的行为,这可能会导致出现乱码消息。除非你使用UNIX套接字。