使用c中的FILE流读取/写入套接字

时间:2009-05-28 10:01:19

标签: c sockets

我发现了一个很好的抽象,我可以使用FILE从UDP读取数据。这对于读取数据非常有用,但是我无法通过UDP吐出数据。以下是通过FILE流读取UDP数据的代码:

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

'written'将返回写入的正数元素,但似乎没有生成UDP数据包。

我想做的是什么?有关为什么它可能无法正常工作的任何建议吗?

3 个答案:

答案 0 :(得分:1)

您没有隐藏信息,这可能很酷,但您将错误的信息提供给另一段代码,即您的套接字的行为类似于流。我认为你应该坚持读/写电话,否则你会发现自己有leaky abstraction

答案 1 :(得分:1)

刷新文件。网络数据包仅在它们已满或强制刷新时生成。因此,除非您写入超过1500个字节(默认值,包括标题字段),否则计算机将等待传送。

答案 2 :(得分:1)

这实际上非常奇怪。使用fflush(),或者更好的是,使用send()代替fwrite()并抛弃FILE。由于FILE对象如何被缓冲的语义以及如何保证数据报不按顺序到达/到达,您将遇到意外的行为,这可能导致消息乱码。除非您使用的是UNIX套接字。

相关问题