C снабжает клиент-серверную задержку сокетом

Я программирую приложение сокетов клиента/сервера C/C++. На данном этапе клиент подключает itselfs к серверу каждые 50 мс и отправляет сообщение.

Все кажется работам, но поток данных не непрерывен: Внезапно, сервер не делает получает что-либо больше и затем 5 сообщений сразу... И иногда все работает...

У кого-то есть идея источника этого странного поведения?

Некоторая часть кода:

Клиент:

while (true)
{
if (SDL_GetTicks()-time>=50)
{
socket = new socket();
socket->write("blah");
message.clear();
message = socket->read();
socket->close();
delete socket;
time=SDL_GetTicks();
}
}

Сервер:

while (true) {
fd_set readfs;
struct timeval timeout={0,0};
FD_ZERO(&readfs);
FD_SET(sock, &readfs);
select(sock + 1, &readfs, NULL, NULL, &timeout)
if(FD_ISSET(sock, &readfs))
{
SOCKADDR_IN csin;
socklen_t crecsize = sizeof csin;
SOCKET csock = accept(sock, (SOCKADDR *) &csin, &crecsize);
sock_err = send(csock, buffer, 32, 0);
closesocket(csock);
}
}

Редактирования: 1. Я пытался сделать

int flag = 1;
setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag);

В обоих клиентах и серверах, но проблеме все еще там.

2. Да те connections/deconnections очень inneficient, но когда я пытаюсь записать

socket = new socket();
while (true)
{
if (SDL_GetTicks()-time>=50)
{
socket->write("blah");
message.clear();
message = socket->read();
time=SDL_GetTicks();
}
}

Затем сообщение только отправлено однажды (или получено)...

Наконец:

Я забыл применять TCP_NODELAY к клиентскому сокету на стороне сервера. Теперь это работает отлично! Я поместил процессы в потоки так, чтобы сокеты сохранили открытыми. Спасибо всем :)

7
задан Klaus 28 February 2010 в 12:57
поделиться

3 ответа

Это то, что называется « задержка Нэгла ». Этот алгоритм ожидает поступления дополнительных данных в стек TCP, прежде чем отправлять что-либо в сеть, пока не истечет некоторый тайм-аут. Поэтому вам следует изменить тайм-аут Nagle ( http://fourier.su/index.php?topic=249.0 ) или вообще отключить задержку Nagle ( http://www.unixguide.net/ network / socketfaq / 2.16.shtml ), поэтому данные будут отправляться при вызове send .

9
ответ дан 6 December 2019 в 11:48
поделиться

Вы можете использовать опцию сокета TCP_NODELAY для немедленной отправки данных.

3
ответ дан 6 December 2019 в 11:48
поделиться

Как уже писали другие, задержки, которые вы видите, связаны со встроенным TCP алгоритмом Нэгла , который можно отключить, установив TCP_NODELAY вариант розетки.

Я хотел бы указать вам на тот факт, что ваши соединения сокетов очень неэффективны из-за постоянных подключений и отключений. Каждый раз, когда клиент подключается к серверу, происходит трехстороннее рукопожатие , а для разрыва соединения требуется четыре пакета для завершения. По сути, вы теряете большую часть преимуществ TCP, но терпите все его недостатки.

Было бы намного более эффективным для каждого клиента поддерживать постоянное соединение с сервером. select (2) , или даже лучше, epoll (4) в Linux или kqueue (2) в FreeBSD и Mac, очень удобные фреймворки для обработки IO на нескольких сокетах.

5
ответ дан 6 December 2019 в 11:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: