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

时间:2022-05-01 21:16:28

I discovered a nice abstraction whereby I can read in data from UDP using a FILE. This works great for reading in data, but I cannot get it to work for spitting out data over UDP. Here is the code for reading in the UDP data over a FILE stream:

我发现了一个很好的抽象,我可以使用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");

Now some other code can call:

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

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

This works fine. However, the reverse doesn't seem to:

这很好用。但是,相反的情况似乎并非如此:

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

Some other code will call:

其他一些代码会调用:

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

'written' will return a positive number of elements written, yet no UDP packets seem to be generated.

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

Is what I am trying to do possible? Any suggestions as to why it might not be working?

我正在尝试做什么?有关为什么它可能无法正常工作的任何建议?

3 个解决方案

#1


Flush the FILE. Network packets are only generated when they are full or when you force a flush. So unless you write more than 1500 bytes (the default, including header fields), the computer will wait with the delivery.

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

#2


You are not hiding information, which might be cool, but you are giving false information to the other piece of code, ie that your socket behaves like a stream. I think you should stick with read / write call, or you will find yourself with a leaky abstraction

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

#3


This is actually pretty weird. Use fflush(), or better yet, use send() instead of fwrite() and ditch the FILE. You will encounter unexpected behavior due to the semantics of how FILE objects are buffered and how datagrams are not guaranteed to arrive in order / arrive at all, this can result in garbled messages. Unless you're using UNIX sockets.

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

#1


Flush the FILE. Network packets are only generated when they are full or when you force a flush. So unless you write more than 1500 bytes (the default, including header fields), the computer will wait with the delivery.

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

#2


You are not hiding information, which might be cool, but you are giving false information to the other piece of code, ie that your socket behaves like a stream. I think you should stick with read / write call, or you will find yourself with a leaky abstraction

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

#3


This is actually pretty weird. Use fflush(), or better yet, use send() instead of fwrite() and ditch the FILE. You will encounter unexpected behavior due to the semantics of how FILE objects are buffered and how datagrams are not guaranteed to arrive in order / arrive at all, this can result in garbled messages. Unless you're using UNIX sockets.

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