Чтение / запись в сокет с использованием потока FILE в c - PullRequest
2 голосов
/ 28 мая 2009

Я обнаружил хорошую абстракцию, благодаря которой я могу читать данные из UDP с помощью ФАЙЛА. Это прекрасно работает для чтения данных, но я не могу заставить его работать, выплевывая данные через UDP. Вот код для чтения в данных UDP через поток FILE:

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-пакеты не генерируются.

Возможно ли то, что я пытаюсь сделать? Любые предложения относительно того, почему это может не работать?

Ответы [ 3 ]

1 голос
/ 28 мая 2009

Очистить файл. Сетевые пакеты генерируются только тогда, когда они заполнены или когда вы вызываете сброс. Поэтому, если вы не напишите более 1500 байт (по умолчанию, включая поля заголовка), компьютер будет ожидать доставки.

1 голос
/ 28 мая 2009

Это на самом деле довольно странно. Используйте fflush (), или еще лучше, используйте send () вместо fwrite () и исключите ФАЙЛ. Вы столкнетесь с неожиданным поведением из-за семантики того, как объекты FILE буферизуются, и как дейтаграммы не гарантированно поступают в порядке / приходят вообще, это может привести к искаженным сообщениям. Если вы не используете сокеты UNIX.

1 голос
/ 28 мая 2009

Вы не скрываете информацию, которая может быть классной, но вы даете ложную информацию другому фрагменту кода, то есть, что ваш сокет ведет себя как поток. Я думаю, вам следует придерживаться вызова чтения / записи, иначе вы обнаружите неплотную абстракцию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...