#c #sockets #newline
#c #сокеты #новая строка
Вопрос:
Я новичок в программировании сокетов. Я написал код для receiver:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<string.h>
#include<unistd.h>
int main()
{int ret= socket(AF_INET,SOCK_DGRAM,0);
if (ret==-1)
{printf("nsocket creation fails");
exit (0);}
else
printf("nsocket creation succeeds");
struct sockaddr_in sender;
int port;
printf("nEnter port:");
scanf("%d",amp;port);
sender.sin_family= AF_INET;
sender.sin_port=htons(port);
sender.sin_addr.s_addr=INADDR_ANY;
int ret1;
ret1= bind(ret,(struct sockaddr *)amp;sender,sizeof(sender));
if(ret1==-1)
{printf("nsocket binding fails");
exit (0);}
else
printf("nsocket binding succeeds");
struct sockaddr_in receiver;
char str[15];
int addrlen=sizeof(receiver);
while(1)
{int rec=recvfrom(ret,str,sizeof(str),0,(struct sockaddr*)amp;receiver,amp;addrlen);
printf("nreceived");
str[rec]='';
if(strcmp(str,"exit")==0)
break;
if (rec==-1)
{printf("nrecvfrom fails");
exit (0);}
else
{printf("nrecv succeeds");
printf("n%s",str);}
}
close(ret);
return 0;
}
Вывод для этого кода печатается received
затем recv succeeds
в следующей строке, после чего курсор переходит к следующей строке, но не выводит str. Однако на следующей итерации while более старое значение str печатается перед received
и recv succeeds
. Эта проблема была решена, когда я использовал
printf("%sn",str)
вместо printf("n%s",str)
. Почему это происходит?
Комментарии:
1. Потому что
stdout
по умолчанию «строка с буферизацией», т.Е. … данные выводятся построчно (а строка определяется как последовательность символов, включающая и заканчивающаяся вводом). Ваш лучший вариант — прекратить печать с помощью"n"
; но вы можете попробовать изменить метод буферизацииstdout
с помощью maybesetvbuf()
или принудительно выполнить вывод в любое время с помощьюfflush()
2. Спасибо! Таким образом, это означает, что ОС не печатает str, потому что она обрабатывает ранее встреченный » n» как конец str. Я правильно понимаю?
Ответ №1:
Стандартный выходной поток, stdout
, обычно буферизуется по строке, когда он направляется на терминал. Согласно C 2018 7.21.3 3:
… Когда поток буферизован по строкам, символы предназначены для передачи в среду хоста или из нее в виде блока при обнаружении символа новой строки. Кроме того, символы предназначены для передачи в виде блока в среду хоста при заполнении буфера, когда ввод запрашивается в небуферизованном потоке или когда ввод запрашивается в потоке с буферизацией строк, который требует передачи символов из среды хоста…
Таким образом, символы после символа новой строки остаются в буфере (внутри памяти компьютера, не отображаются на устройстве вывода) до тех пор, пока не будет записан символ новой строки, или вы не запросите ввод (как с scanf
) в связанном потоке ввода, или вы явно не запросите очистку буфера, или записано так много, что буфер заполнен.
По этой причине не рекомендуется писать printf
инструкции с использованием символов новой строки в начале, таких как "nrecv succeeds"
. C был разработан для вывода символов новой строки в концах строк для обычных приложений, таких как "recv succeedsn"
.
Комментарии:
1. Понял. Большое спасибо!