LINUX.ORG.RU

Тупняк с сокетами

 ,


0

0
if (send(this->socket_desc, message.c_str(), message.length(), 0) >= 0)
{
	ssize_t size_recv;
	char chunk[HTTP_RECV_CHUNK_SIZE];
		
	//fcntl(this->socket_desc, F_SETFL, O_NONBLOCK);
		
	do
	{
		memset(chunk, 0, HTTP_RECV_CHUNK_SIZE);
		size_recv = recv(this->socket_desc, chunk, HTTP_RECV_CHUNK_SIZE, 0);
		std::cout << size_recv << std::endl;
		response += chunk;
	}
	while(size_recv > 0);
}

Как сделать, чтобы по завершению передачи выйти из цикла? Сейчас на последнем recv все зависает, ну и как я понимаю чего-то ожидает.

★★★★

man aio

If no messages are available at the socket and O_NONBLOCK is not set on the socket's file descriptor, recv() shall block until a message arrives. If no messages are available at the socket and O_NONBLOCK is set on the socket's file descriptor, recv() shall fail and set errno to [EAGAIN] or [EWOULDBLOCK].

Stil ★★★★★
()
Ответ на: комментарий от FIL

тебе сервер в заголовке шлет размер. считываешь заголовок, считываешь тело до тех пор, пока не получил столько, сколько сказал сервер.

в маил сру чтоль задачу дали на собеседовании?

vvviperrr ★★★★★
()
Последнее исправление: vvviperrr (всего исправлений: 1)
Ответ на: комментарий от vvviperrr

тебе сервер в заголовке шлет размер

всегда ли?

в маил сру чтоль задачу дали на собеседовании?

лол, нет

FIL ★★★★
() автор топика
Ответ на: комментарий от Stil

неблокирующий сокет ему ничем не поможет в данном случае

vvviperrr ★★★★★
()

просто откоменчу ваш код:

// чё-то отсылаем, и если хоть часть ушла - будем читать
if (send(this->socket_desc, message.c_str(), message.length(), 0) >= 0)
{
	ssize_t size_recv;
	char chunk[HTTP_RECV_CHUNK_SIZE]; // этот массив в стеке
		
	//fcntl(this->socket_desc, F_SETFL, O_NONBLOCK);
		
	do
	{
                // пройдём нулями по стеку, проц.должен что-то делать
		memset(chunk, 0, HTTP_RECV_CHUNK_SIZE);
                // забъём свежие нули более свежими байтами
		size_recv = recv(this->socket_desc, chunk, HTTP_RECV_CHUNK_SIZE, 0);
                // напечатать сколько нулей погибло
		std::cout << size_recv << std::endl;
                // добавить куда-то НЁХ (адрес в стеке)
		response += chunk;
	}
	while(size_recv > 0); // пока коннект не отвалится - повторять
}

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

// чё-то отсылаем, и если хоть часть ушла - будем читать

На самом деле не отсылаем, а лишь копируем в буфер обмена. А так как он почти всегда (я не уверен, что можно сделать буфер меньше 4K, поэтому всегда) больше, чем размер HTTP GET запроса (никто же не поверит, что ТС POST'ом отправляет файло больше 64K), то этот код почти всегда работает, как ожидается.

P.S. Недавно хотел потестировать разницу в работе однопоточного, многопоточного и асинхронного сетевого кода с точки зрения производительности, но так и не понял, как это сделать, ибо если сервер и клиент на локальной машине, то все разумные размеры файлов, которые гоняют по HTTP влезают в буффер за один раз, т.е. как отправка, так и прием происходят за одно чтение/запись. В результате код, который обеспечивает синхронизацию потоков и другие вспомогательные действия влияет гораздо сильнее, чем сама асинхронность обмена данными. В общем, я так и не придумал серьезных преимуществ асинхронности, если клиент не отправляет данные серверу по чайной ложке за час.

anonymous
()
Ответ на: комментарий от anonymous

Надо было всего лишь запустить не 1, а 10K клиентов. И смотреть не латентность обслуживания одного клиента, а пропускную способность сервера, обслуживающего 10K клиентов.

iliyap ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.