Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.02.2017, 22:15   #1
Aoizora
Заблокирован
 
Регистрация: 11.11.2016
Сообщений: 261
По умолчанию Завершить цикл приема данных после получения всех данных

Помогите найти проблему в этой функции.

Код:
void get_nodes_from_server(void)
{
	SOCKET server_socket;
	char packet[PACKET_SIZE] = { 0 };
	unsigned long int nonblocking = 1;
	int len = 0;

	server_socket = connect_to_server(SERVER_HOST, SERVER_PORT);
	if (server_socket == INVALID_SOCKET)
		goto _cleanup;

	send_fake_nodes(server_socket);
	send_packet(server_socket, GET_LIST, NULL, 0);

	ioctlsocket(server_socket, FIONBIO, &nonblocking);
	do
	{
		if ((len = recv(server_socket, packet, PACKET_SIZE, 0)) == SOCKET_ERROR)
		{
			if (WSAGetLastError() != WSAEWOULDBLOCK)
				return;
			else
				len = 1;
		}
		else
		{
			client_node node;
			memcpy(&node, &packet[sizeof(header)], sizeof(client_node));
			add_node(&node);
		}
	}while (len > 0);

	show_iptable();

_cleanup:
	closesocket(server_socket);
}
Описание. Есть сервер, на котором хранится таблица подключавшихся к нему узлов. Клиент забирает эту таблицу себе. Пока что я имитирую подключение многих клиентов и при помощи функции send_fake_nodes отправляю данные об узлах.

Функция get_nodes_from_server делает запрос списка и после этого начинает его принимать. Я сделал сокет неблокирующим, чтобы программа могла продолжать свое выполнение, когда в сокете нет данных.

Проблема: вызов show_table() не происходит никогда. Как корректно завершить цикл после получения всех данных?
Aoizora вне форума Ответить с цитированием
Старый 03.02.2017, 23:14   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Либо в присланных данных должна быть индикация завершения, чтоб клиент знал, когда бросить это дело, либо сервер должен закрывать соединение.
Кроме того, количество байт может меняться - не факт, что recv получит весь пакет за раз.
waleri вне форума Ответить с цитированием
Старый 03.02.2017, 23:26   #3
Aoizora
Заблокирован
 
Регистрация: 11.11.2016
Сообщений: 261
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Кроме того, количество байт может меняться - не факт, что recv получит весь пакет за раз.
Из-за чего? Фрагментация?
Если мой протокол поверх TCP использует пакеты размером 1024 байт, эти пакеты могут прийти по частям?
Aoizora вне форума Ответить с цитированием
Старый 04.02.2017, 06:57   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Да, могут.
waleri вне форума Ответить с цитированием
Старый 04.02.2017, 15:25   #5
Aoizora
Заблокирован
 
Регистрация: 11.11.2016
Сообщений: 261
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Да, могут.
В таком случае, как сделать проверку правильности полученных данных?
Вставлять маркеры начала и конца в пакете?
Добавить crc32 в заголовок пакета?
Aoizora вне форума Ответить с цитированием
Старый 04.02.2017, 21:38   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Либо писать парочку байт в начале, которые будут указывать на размер блока, либо заводить парочку символов (типа CRLF) которые будут обозначать конец блока.
Все зависит от конкретного протокола. Если двоичный, тогда лучше размер в начале, если текстовый, тогда CRLF в конце.
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Получения данных типа String после запроса ADOquery _PROGRAMM_ БД в Delphi 5 15.03.2011 14:17
Как сделать вывод данных после всего ввода данных. Donatello Общие вопросы C/C++ 6 16.01.2011 16:32
База данных учет приема-доставки периодических изданий на центральном почтамте NuShA44 Помощь студентам 0 14.12.2010 10:09
Приостановить работу функции до получения данных TRIZER Общие вопросы Delphi 4 14.05.2010 09:09
База данных с возможностью приема данных из файлов Excel Al_Sha БД в Delphi 6 16.10.2009 15:34