The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа
Дальше: Приложение C. Практические задания Вверх: socket Назад: Приложение А. Реализация протокола

Приложение B. Реализация протокола Daytime с использованием TCP

Теперь рассмотрим реализацию протокола daytime при помощи протокола TCP. Как и в UDP, сервер занимает порт 13 и ожидает поступления запросов на установление соединения. После установления соединения, сервер отправляет клиенту строку, содержащую дату и время, и закрывает соединение. Реализация сервера приведена ниже:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

main() {
	int s, c, sz;
	struct sockaddr_in ssa, csa;
	struct sockaddr *sp, *cp;
	struct hostent *rhost;
	char *host, *tstr;
	time_t itime;

	sp=(struct sockaddr *)&ssa;
	cp=(struct sockaddr *)&csa;
	sz=sizeof(ssa);

	// Создаём сокет
	s=socket(AF_INET, SOCK_STREAM, 0);
	if(s == -1){
		perror("Невозможно создать сокет");
		exit(1);
	}

	// Резервируем порт 13
	ssa.sin_family = AF_INET;
	ssa.sin_port = htons(13);
	ssa.sin_addr.s_addr = INADDR_ANY;

	if(bind(s, sp, sz) == -1){
		perror("Невозможно занять порт");
		exit(1);
	}

	// Переводим сокет в режим ожидания соединения
	if(listen(s, 0) == -1){
		perror("Невозможно перейти в режим ожидания");
		exit(1);
	}

	while(1){
		// Принимаем соединение
		if((c = accept(s, cp, &sz)) == -1) {
			perror("Ошибка при выполнении accept");
			exit(1);
		}
		
		// Преобразуем адрес хоста отправителя в его имя
		rhost=gethostbyaddr((char*)(&csa.sin_addr), 
				sizeof(csa.sin_addr), AF_INET);
		if(h_errno){
			printf("gethostbyaddr error: %d\n", h_errno);
			host=inet_ntoa(csa.sin_addr);
		} else {
			host=rhost->h_name;
		}

		// Получаем строку, содержащую дату и время
		if((itime = time(NULL)) < 0){
			perror("Не удалось получить время");
			exit(1);
		}
		tstr = ctime(&itime);

		// Выводим время поступления запроса,
		// адрес и порт отправителя
		printf("%s request from %s:%d\n", tstr, host,
				htons(csa.sin_port));

		// Отправляем дату и время клиенту
		send(c, tstr, strlen(tstr), 0);

		// Закрываем соединение
		close(c);
	}
}

Теперь рассмотрим реализацию клиента. Обратите внимание, что клиент не должен выполнять вызов функции bind, порт выделяется автоматически при выполнении connect.


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFSZ 128

main(int argc, char *argv[]) {
	int s, sz, i;
	struct sockaddr_in ssa;
	struct sockaddr *sp;
	struct in_addr sip;
	char buf[BUFSZ];

	sp=(struct sockaddr *)&ssa;
	sz=sizeof(ssa);

	if(argc!=2){
		// Помощь по использованию команды
		printf("Использование: %s ip-адрес\n",argv[0]);
		exit(1);
	}
	if(inet_aton(argv[1], &sip) != 1){
		printf("Неправильно задан адрес сервера\n");
		exit(1);
	}
	// Создаём сокет
	s=socket(AF_INET, SOCK_STREAM, 0);
	if(s == -1){
		perror("Невозможно создать сокет");
		exit(1);
	}

	// Задаём адрес сервера
	ssa.sin_family = AF_INET;
	ssa.sin_port = htons(13);
	ssa.sin_addr = sip;

	// Устанавливаем соединение
	if(connect(s, sp, sz) == -1){
		perror("Не удалось установить соединение");
		exit(1);
	}

	// Получаем данные от сервера
	while((i=recv(s, buf, BUFSZ, 0)) > 0)
		write(1, buf, i);

}



Zwon
2002-03-24



Спонсоры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2022 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру