powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / recv выход из цикла
25 сообщений из 178, страница 1 из 8
recv выход из цикла
    #39709671
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть проблема чтения данных из сокета, а именно - протокол TCP/IP передает поток байтов от сервера к клиенту пакетами.
Размер пакетов имеет разную длину, которые помещаются в буфер, из которого функция recv и считывает данные

Приходится читать их в цикле.
Проблема в том, что, при завершении приема данных, функция recv переходит в режим ожидания следующего пакета.

Пример кода:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
	while (res>0)
	{	
	res = recv(sock, rbuff, sizeof(rbuff), 0);    

	tmp = cp1251toUtf8(rbuff,res);

	}



Цикл выбирает все данные из буфера и останавливается в режиме ожидания на строке

Код: plaintext
1.
	res = recv(sock, rbuff, sizeof(rbuff), 0);    



Какие есть варианты выхода из цикла?
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709675
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Одно из двух:
1. Ты должен знать заранее сколько байт надо прочитать, т.е. перед данными передается их размер.
2. Есть какой-то маркер конца данных. Т.е. надо проверять что в принятом есть этот маркер.

Обычно делают по первому варианту.
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709683
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rb,

почитай про setsockopt и опцию SO_RCVTIMEO
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709685
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TОдно из двух:
1. Ты должен знать заранее сколько байт надо прочитать, т.е. перед данными передается их размер.
2. Есть какой-то маркер конца данных. Т.е. надо проверять что в принятом есть этот маркер.

Обычно делают по первому варианту.

Первый вариант не подходит, а второй можно попробовать
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709721
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rb,

Делаешь сокет O_NONBLOCK и читаешь в цикле пока recv не вернёт ошибку EWOULDBLOCK
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709736
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rbесть проблема чтения данных из сокета, а именно - протокол TCP/IP передает поток байтов от сервера к клиенту пакетами.


Нет, ты ошибаешься, передача TCP идёт потоком. Пакетов никаких нет.


авторРазмер пакетов имеет разную длину, которые помещаются в буфер, из которого функция recv и считывает данные

Приходится читать их в цикле.
Проблема в том, что, при завершении приема данных, функция recv переходит в режим ожидания следующего пакета.

Пример кода:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
	while (res>0)
	{	
	res = recv(sock, rbuff, sizeof(rbuff), 0);    

	tmp = cp1251toUtf8(rbuff,res);

	}



Цикл выбирает все данные из буфера и останавливается в режиме ожидания на строке

Код: plaintext
1.
	res = recv(sock, rbuff, sizeof(rbuff), 0);    



Какие есть варианты выхода из цикла?

recv возвращает отрицательное число при закрытии сокета и прочих проблемах.
Вот это и надо проверять.
Всё это есть в документации.
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709740
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Ты должен знать заранее сколько байт надо прочитать, т.е. перед данными передается их размер.

Это не обязательно.
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709749
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rbпротокол TCP/IP передает поток байтов от сервера к клиенту пакетами.

"Неправильно ты, дядя Фёдор, бутерброд ешь."
Надо говорить так: "протокол TCP/IP передает поток байтов". Точка. Никакого разделения на
"пакеты", видимые прикладному уровню, в нём нет.

Sergey_rbПроблема в том, что, при завершении приема данных, функция recv переходит в режим ожидания
следующего пакета.

Это не проблема. Проблема в том, что ты принятые байты не обрабатываешь сразу по принятии.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709774
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivSergey_rbесть проблема чтения данных из сокета, а именно - протокол TCP/IP передает поток байтов от сервера к клиенту пакетами.


Нет, ты ошибаешься, передача TCP идёт потоком. Пакетов никаких нет.


авторРазмер пакетов имеет разную длину, которые помещаются в буфер, из которого функция recv и считывает данные

Приходится читать их в цикле.
Проблема в том, что, при завершении приема данных, функция recv переходит в режим ожидания следующего пакета.

Пример кода:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
	while (res>0)
	{	
	res = recv(sock, rbuff, sizeof(rbuff), 0);    

	tmp = cp1251toUtf8(rbuff,res);

	}



Цикл выбирает все данные из буфера и останавливается в режиме ожидания на строке

Код: plaintext
1.
	res = recv(sock, rbuff, sizeof(rbuff), 0);    



Какие есть варианты выхода из цикла?

recv возвращает отрицательное число при закрытии сокета и прочих проблемах.
Вот это и надо проверять.
Всё это есть в документации.

Сокет не закрывается после получения данных
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709779
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rbDima TОдно из двух:
1. Ты должен знать заранее сколько байт надо прочитать, т.е. перед данными передается их размер.
2. Есть какой-то маркер конца данных. Т.е. надо проверять что в принятом есть этот маркер.

Обычно делают по первому варианту.

Первый вариант не подходит, а второй можно попробовать

Второй вариант не прокатил, т.к. в потоке есть символы перевода строки
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709780
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rbСокет не закрывается после получения данных

Поэтому-то твой цикл и не завершается. Обрабатывая данные внутри него.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709800
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovSergey_rbСокет не закрывается после получения данных

Поэтому-то твой цикл и не завершается. Обрабатывая данные внутри него.


Не закрывается, потому что так устроен обмен.

Увеличил размер буфера, чтобы в него гарантированно помещался весь объем принятых данных,
Каждый раз размер данных получается разный. потому что передача идет пакетами, причем размер пакетов произвольный, поэтому считывать надо в цикле.
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709812
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rbКаждый раз размер данных получается разный. потому что передача идет пакетами, причем
размер пакетов произвольный, поэтому считывать надо в цикле.

Ты ещё не знаешь, что пакеты могут как делиться на части, так и склеиваться в один.
Повторяю медленно: обрабатывай каждую принятую порцию данных внутри своего цикла.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709831
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovSergey_rbКаждый раз размер данных получается разный. потому что передача идет пакетами, причем
размер пакетов произвольный, поэтому считывать надо в цикле.

Ты ещё не знаешь, что пакеты могут как делиться на части, так и склеиваться в один.
Повторяю медленно: обрабатывай каждую принятую порцию данных внутри своего цикла.


Я их обрабатываю
Мне надо знать, когда функция recv считала последний пакет.

проверка на количество считанных байтов не подходит, т.к. оно больше 0
Проверка на наличие символа \n тоже не прокатывает, т.к. в пакете есть символы перевода строки.
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709833
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В INDY сначала считывается количество полученных строк, затем считываются строки.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
procedure TIdTCPConnection.ReadStrings(var AValue: TStrings; AReadLinesCount: Integer = -1);
Var
  i: Integer;
begin
  if AReadLinesCount <= 0 then begin
    AReadLinesCount := ReadInteger;
  end;
  for i := 0 to AReadLinesCount - 1 do begin
    AValue.Add(ReadLn);
  end;
end;
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709849
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rbМне надо знать, когда функция recv считала последний пакет.

Не существует в природе никакого "последнего пакета". За исключением того, после которого
соединение закрывается.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709851
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rbВ INDY сначала считывается количество полученных строк

Значит инди сначала передаёт количество передаваемых строк. О чём тебе и говорили:
передавай длину данных перед самими данными.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709855
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovSergey_rbМне надо знать, когда функция recv считала последний пакет.

Не существует в природе никакого "последнего пакета". За исключением того, после которого
соединение закрывается.


да не закрывается соединение.
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709865
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovSergey_rbВ INDY сначала считывается количество полученных строк

Значит инди сначала передаёт количество передаваемых строк. О чём тебе и говорили:
передавай длину данных перед самими данными.


Не могу я менять алгоритм работы сервера, т.к. на нем крутятся терминалы
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709970
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну тогда ничего не поделаешь, придётся применять мозг или нанимать программиста.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
recv выход из цикла
    #39709975
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovНу тогда ничего не поделаешь, придётся применять мозг или нанимать программиста.


Так где же взять этого программиста?
...
Рейтинг: 0 / 0
recv выход из цикла
    #39710008
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локализовал проблему - при получении 2-х пакетов, теряется первый пакет, т.е. функция выдает к-то байт, но сам буфер пустой.
Поставил
Код: plaintext
1.
Sleep(100)



Не помогло.

Есть подозрение, что буфере остается мусор от предыдущих запросов
...
Рейтинг: 0 / 0
recv выход из цикла
    #39710042
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rbпри получении 2-х пакетов, теряется первый пакет, т.е. функция выдает к-то байт, но сам
буфер пустой.

Что логично, поскольку ты и принимаешь в один буфер и складываешь в одно место, так что
каждый следующий принятый кусок затирает предыдущий. Включи уже голову.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
recv выход из цикла
    #39710060
Sergey_rb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovSergey_rbпри получении 2-х пакетов, теряется первый пакет, т.е. функция выдает к-то байт, но сам
буфер пустой.

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


если речь идет о этой строке,

авторtmp = cp1251toUtf8(rbuff,res);


То я выложил не всю обработку
Код: plaintext
1.
2.
			tmp = cp1251toUtf8(rbuff,res);
			line.append(tmp);




Первый пакет теряется даже в случает двух вызовов recv

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
		res_total=recv(sock, rbuff, sizeof(rbuff), 0);

		wsprintf(t2, L" res_total = %d", res_total);

		::MessageBoxW(NULL,t2, L"GetStrings", MB_ICONEXCLAMATION | MB_OK);

		i=strlen(rbuff);
		wsprintf(t2, L" strlen = %d", i);

		::MessageBoxW(NULL,t2, L"Buf len", MB_ICONEXCLAMATION | MB_OK);

		tmp = cp1251toUtf8(rbuff,sizeof(rbuff));
		::MessageBoxW(NULL,tmp.c_str(), L"GetStrings total result", MB_ICONEXCLAMATION | MB_OK);

		 res = recv(sock, rbuff, sizeof(rbuff), 0);

		i=strlen(rbuff);
		wsprintf(t2, L" strlen = %d", i);

		::MessageBoxW(NULL,t2, L"GetStrings", MB_ICONEXCLAMATION | MB_OK);


		tmp = cp1251toUtf8(rbuff,sizeof(rbuff));

//		wstr = cp1251toUtf8((const char *)  rbuff, res); 		

		::MessageBoxW(NULL,tmp.c_str(), L"GetStrings result", MB_ICONEXCLAMATION | MB_OK);

		line.append(tmp);
...
Рейтинг: 0 / 0
recv выход из цикла
    #39710076
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey_rbПервый пакет теряется даже в случает двух вызовов recv

Это очередной псевдокод или этот бред реально написан в программе? Он в принципе не
работоспособен от "strlen()" и ниже.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
25 сообщений из 178, страница 1 из 8
Форумы / C++ [игнор отключен] [закрыт для гостей] / recv выход из цикла
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]