Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите пожалуйста. Winsock 1 Гбит/сек нет такой 
:(
    Опции темы
ForNights
Дата 10.3.2011, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



Пишу под WinXP на Builder Cpp использую Winsock протокол TCP/IP на карточке в 100 Мбит/сек достигает скорости в 60-70 Мбит/сек, а вот когда переношу прогу на компьютер с карточкой 1 Гбит/с достигаю скорости 176 Мбит/сек!!!! 
Информацию передаю через один сокет. По моему глубокому убеждению считаю что скорость должна быть, а её нет! 
PM MAIL   Вверх
borisbn
Дата 10.3.2011, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 2
Всего: 135



чем скорость измеряешь ?
какой размер пакета, передаваемого за раз ?
попробуй увеличить его раз в 10-20...


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
ForNights
Дата 10.3.2011, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



Цитата(borisbn @ 10.3.2011,  11:26)
чем скорость измеряешь ?
какой размер пакета, передаваемого за раз ?
попробуй увеличить его раз в 10-20...

Про пакеты ничего не могу сказать, но буфера я менял в пределах от 1500 до 512000 и устанавливал их через setsockopt: 
При отказе от ручного выставления размера буфера, он производит поиск оптимума сам, но на мою задачу это не влияет. 
Код
 
 if (setsockopt(lsock, SOL_SOCKET, SO_SNDBUF, (char*)&lenbuf, sizeof(lenbuf)) == SOCKET_ERROR) {return;}
 if (setsockopt(lsock, SOL_SOCKET, SO_RCVBUF, (char*)&lenbuf, sizeof(lenbuf)) == SOCKET_ERROR){return;}
 //if (setsockopt(lsock, IPPROTO_TCP, TCP_NODELAY, (char *) &boo, sizeof(boo)) == SOCKET_ERROR){return;}
 if (setsockopt(lsock, SOL_SOCKET, SO_RCVTIMEO, (char *)&time, sizeof(time)) == SOCKET_ERROR){return;}
 if (setsockopt(lsock, SOL_SOCKET, SO_SNDTIMEO, (char *)&time, sizeof(time)) == SOCKET_ERROR){return;}
 //if (setsockopt(lsock, SOL_SOCKET, SO_KEEPALIVE, (char*)&keep, sizeof(keep)) == SOCKET_ERROR){return;}

При инициализации глобальные переменные имеют следующие значения: 
count_send_data = 10; 
count_all_data = 0; 
count_loc_data = 0; 
lab = 0;
Код

case 2:
      {
       if (!WSAEnumNetworkEvents(sock, (WSAEVENT)hEvents[2], &wsEvents))
        {
         if (wsEvents.lNetworkEvents & FD_READ)
          {
           if (wsEvents.iErrorCode[FD_READ_BIT])
            {
             ClientMessage = "FD_READ fail. Stopping..";
             Synchronize(write_memo);
             dwDone = 1;
             break;
            }
            else
             {
              do{
                 //принимаем данные
                 nRet = recv (sock, (char*)buf, lenbuf, 0);

                 //обрабатываем принятые данные
                 if (nRet > 0)
                  {
                   buf[nRet-1] = '\0';
                   int len = strlen(buf);
                   for(int i = 0; i <= len; i ++)
                    {
                     sin_data += sin((int)buf[i]);
                    }
                   ClientMessage = buf;

                   //EnterCriticalSection(&cs); // Вход в критическую секцию cs
                   count_all_data += nRet;
                   count_loc_data += nRet;
                   //LeaveCriticalSection(&cs); // Выход из критической секции cs

                   //накапливаем 10 приёмов и подсчитываем скорость
                   if(count_send_data == 10)
                    {
                     Synchronize(timer_timer);
                     ClientMessage = "count_send_data: " + (AnsiString)count_send_data;
                     Synchronize(write_memo);
                     count_send_data = 0;
                    } else { count_send_data ++; }

                   ClientMessage = "DS: " + (AnsiString)count_all_data + ", Ch: " + (AnsiString)nRet + ", sin(x): " + (AnsiString)sin_data + " " + (AnsiString)sock;
                   Synchronize(write_memo);
                  }
                }while (nRet > 0);
              //Synchronize(TestTime);
             }
          }

         if (wsEvents.lNetworkEvents & FD_CLOSE)
          {
           if (wsEvents.iErrorCode[FD_CLOSE_BIT])
            {
             ClientMessage = "FD_CLOSE fail with code " + (AnsiString)wsEvents.iErrorCode[FD_CLOSE_BIT];
             Synchronize(write_memo);

             if (wsEvents.iErrorCode[FD_CLOSE_BIT] == WSAENETDOWN)
              {
               ClientMessage = "Stopping..";
               Synchronize(write_memo);
               dwDone = 1;
               break;
              }
            }
            else
             {
              lab = 2;
              Synchronize(timer_timer);
              sin_data = 0;

              ClientMessage = "Client disconnected.";
              Synchronize(write_memo);
              WSAEventSelect (sock, (WSAEVENT)hEvents[2], 0);
              shutdown (sock, SD_BOTH);
              closesocket (sock);
              dwCount = 2;
             }
          }
        }
        else
         {
          ClientMessage = "WSAEnumNetworkEvent fail with code " + (AnsiString)WSAGetLastError();
          Synchronize(write_memo);
          ResetEvent (hEvents[2]);
         }
      } break;

void __fastcall TWinsockThread::timer_timer()
{
 int t1buf;
 double curtime, speed = 0;
 switch(lab)
  {
   case 0:
    {
     t_begin = t_1 = clock();
     ClientMessage = "0";
     lab = 1;
    } break;
   case 1:
    {
     t1buf = clock();
     curtime = t1buf - t_1;
     speed = count_loc_data;//байты
     //--------->
     count_loc_data = 0;
     t_1 = t1buf;
    } break;
   case 2:
    {
     curtime = (int)clock() - (int)t_begin;
     speed = count_all_data;//байты
     //--------->
     ClientMessage = "count_all_data: " + (AnsiString)count_all_data + " byte";
     write_memo();
     count_all_data = 0;
     lab = 0;
    } break;
  }
 //--------->
 if((speed)&&(curtime))
  {
   speed *= 8;         //биты
   speed /= 1024;      //кбиты
   speed /= 1024;      //мбиты    
   speed /= (curtime*0.001);      //мбиты / секунды
   ClientMessage = "Speed: " + (AnsiString)speed + " mbit/sec";
   write_memo();
  }
 //--------->
 Application->ProcessMessages();
}


Добавлено через 3 минуты и 2 секунды
Но вот воспользовался советом и пустил клиента в 4 потока и сервера в 4, скорость при этом на локал хосте выросла с 176 до ~350 - 700 МБит/сек, но какая то она нестабильная, у меня складывается впечатление что я где то с потоками напортачил, а вернее с подсчётом времени из этих потоков!? Сейчас у меня заведена глобальная переменная в которую потоки плюсуют  количество принятых данных, при приёме десяти порций происходит подсчёт результата.
Внимание вопрос, если я использую один сокет на сервере и один на клиенте, то могу ли я заполнить канал в 1 ГБит/сек, или же мне продолжать мутки с многопоточностью?
PM MAIL   Вверх
boostcoder
Дата 10.3.2011, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(ForNights @  10.3.2011,  13:59 Найти цитируемый пост)
если я использую один сокет на сервере и один на клиенте, то могу ли я заполнить канал в 1 ГБит/сек, или же мне продолжать мутки с многопоточностью?

согласно проводимым мною экспериментам, если только писать в TCP сокет, то получится использовать его приблизительно на 70 процентов от пропускной способности.
если, к примеру, в сокет и пишешь и читаешь из него, то использовать получится приблизительно 20 процентов от пропускной способности.
полагаю, это особенность TCP протокола.

при использовании UDP протокола, такой проблемы нет. но он не гарантирует доставку. именно по этому, разработан протокол UDT. в экспериментах, получаю, приблизительно 76-98 процентов от пропускной способности.
переписывайте клиент-сервер для него.


Это сообщение отредактировал(а) boostcoder - 10.3.2011, 16:10
PM WWW   Вверх
ForNights
Дата 11.3.2011, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



Цитата(boostcoder @ 10.3.2011,  16:08)
Цитата(ForNights @  10.3.2011,  13:59 Найти цитируемый пост)
если я использую один сокет на сервере и один на клиенте, то могу ли я заполнить канал в 1 ГБит/сек, или же мне продолжать мутки с многопоточностью?

согласно проводимым мною экспериментам, если только писать в TCP сокет, то получится использовать его приблизительно на 70 процентов от пропускной способности.
если, к примеру, в сокет и пишешь и читаешь из него, то использовать получится приблизительно 20 процентов от пропускной способности.
полагаю, это особенность TCP протокола.

при использовании UDP протокола, такой проблемы нет. но он не гарантирует доставку. именно по этому, разработан протокол UDT. в экспериментах, получаю, приблизительно 76-98 процентов от пропускной способности.
переписывайте клиент-сервер для него.

Благодарю за направление и думаю что в ближайшее время взгляну в сторону UDT, но вот про чтение запись в сокет не согласен! Я в клиенте только записываю в сокет, а на стороне сервера только читаю, и если я бы получил 70% скорости от гигабитного канала то был бы просто счастлив, а мои 176 МБит/сек покрывают только ~20% от канала!???
PM MAIL   Вверх
Олег2005
Дата 11.3.2011, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(ForNights @  11.3.2011,  09:29 Найти цитируемый пост)
а мои 176 МБит/сек покрывают только ~20% от канала!??? 

Виндовс может резервировать часть пропускной способности канала - и не отдавать ее в пользование пользователя
PM MAIL WWW MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0486 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.