/** * В.Д.Валединский * Простейший пример TCP клиента и сервера. * * Файлы * cli_tcp.cpp - пример TCP клиента * ser_tcp_select.cpp - пример TCP сервера c использованием select() * ser_tcp_poll.cpp - пример TCP сервера c использованием poll() * ser_tcp_fork.cpp - пример TCP сервера c использованием fork() * ser_tcp_prefork.cpp - пример TCP сервера c использованием fork() * * Клиент в цикле получает с клавиатуры текстовую строку и отсылает * ее на сервер, читает и выводит на экран ответ сервера. * Сервер ждет соединений от клиентов. При установленом * соединении получает строку от клиента, переводит ее в верхний * регистр и отсылает обратно клиенту. Если клиент посылает строку * содержащую слово stop, то сервер закрывает соединение с этим клиентом, * а клиент заканчивает свою работу. * Клиент и сервер печатают на экран протокол своей работы т.е. * разные данные, которые они получают или отсылают. * * Для ясности примеры составлены максимально просто и не анализируют * некорректные ответы и запросы клиента и сервера, возможность переполнения * буферов ввода вывода, неожиданное 'падение' сервера и т.п. * */ #include #include #include #include #include #include #include #include #include #include #include #include // Определимся с номером порта и другими константами. #define PORT 5555 #define BUFLEN 512 // Две вспомогательные функции для чтения/записи (см. ниже) int readFromClient(int fd, char *buf); void writeToClient (int fd, char *buf); int main (void) { int i, err, opt=1; int sock, new_sock; struct sockaddr_in addr; struct sockaddr_in client; char buf[BUFLEN]; socklen_t size; // Создаем TCP сокет для приема запросов на соединение sock = socket (PF_INET, SOCK_STREAM, 0); if ( sock<0 ) { perror ("Server: cannot create socket"); exit (EXIT_FAILURE); } // опция чтобы не ждать при повторном запуске сервера setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const void*)&opt,sizeof(opt)); // Заполняем адресную структуру и // связываем сокет с любым адресом addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); err = bind(sock,(struct sockaddr*)&addr,sizeof(addr)); if ( err<0 ) { perror ("Server: cannot bind socket"); exit (EXIT_FAILURE); } // Создаем очередь на 3 входящих запроса соединения err = listen(sock,3); if ( err<0 ) { perror ("Server: listen queue failure"); exit(EXIT_FAILURE); } // Подготавливаем множества дескрипторов каналов ввода-вывода. pollfd act_set[100]; act_set[0].fd = sock; act_set[0].events = POLLIN; // requested event act_set[0].revents = 0; // returned event int num_set = 1; // Основной бесконечный цикл проверки состояния сокетов while (1) { // Проверим, не появились ли данные в каком-либо сокете. // В нашем варианте ждем до фактического появления данных. int ret = poll (act_set, num_set, -1); if (ret < 0) { perror("Server: poll failure"); exit (EXIT_FAILURE); } if (ret > 0) { for (i=0; i