Превратите простую программу C в сервер с помощью netcat

Одна интересная особенность netcat заключается в том, что он может превратить любую программу командной строки в сервер. Например, в системах Unix мы можем создать простой сервер даты, передав двоичный файл date в netcat, чтобы он stdout отправлялся через сокет:

netcat -l -p 2020 -e date

Затем мы можем вызвать эту службу с другой машины, просто введя команду:

netcat <ip-address> 2020

Можно подключить даже оболочку (/bin/sh), хотя я знаю, что это крайне не рекомендуется и имеет большие последствия для безопасности.

Точно так же я попытался написать свою собственную простую программу на C, которая одновременно читает и записывает из stdin и stdout:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    char buffer[20];
    printf("Please enter your name:\n");
    fgets(buffer, 20, stdin);
    printf("Hello there, %s\n", buffer);
    return 0;
}

Однако, когда я вызываю службу с другого терминала, начального приветствия нет; на самом деле приветствие печатается только после отправки некоторой информации. Например:

user@computer:~$ netcat localhost 2020
User
Please enter your name:
Hello there, User

Что мне нужно сделать, чтобы мое приветствие сначала было отправлено через сокет, затем дождаться ввода, а затем отправить окончательное сообщение (точно так же, как я напрямую вызываю двоичный файл)?

Я знаю, что могут быть лучшие (и, возможно, более безопасные) подходы к реализации такой системы, но мне любопытны особенности netcat и почему это не работает.


person Peter    schedule 04.03.2014    source источник


Ответы (1)


Существует высокая вероятность того, что stdout не буферизируется строкой при записи на нетерминал. Сделайте fflush(stdout) сразу после printf.

person cnicutar    schedule 04.03.2014
comment
Вы также можете использовать dprintf(), который не выполняет буферизацию. - person Jean; 05.03.2014
comment
@Phibonacci Звездное предложение, если у вас есть файловый дескриптор. - person cnicutar; 05.03.2014
comment
Спасибо за вашу помощь, ребята, это действительно указало мне правильное направление. Я только что нашел другое решение, которое хорошо работает. Буферизацию также можно отключить, вызвав setbuf, например: setbuf(stdout, NULL); - person Peter; 07.03.2014