Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Интернет и сети
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 28.06.2010, 13:31
Master255 Master255 вне форума
Прохожий
 
Регистрация: 28.06.2010
Сообщения: 8
Репутация: 10
По умолчанию Приоритет обработки сокетов

Проблема в том что при отправке данных через сокет сначало всё нормально, но если запустить ёмкую программу, то обработка отправки прерывается. Прерывание возможно происходит на миллисекунды, но это критически важно. Что бы не было прерываний. Передаётся звук. Как увеличить приоритет отправки (send) и приёма данных?

Вот листинги того что есть сейчас:
Отправка буфера:
Код:
function WlanSendBuffer(Buffer: Pointer; DataSize: Integer): Boolean;
var
  AmountSent: Integer;
  Position : Integer;
  BytesLeftToWrite: Integer;
  BytesToWrite: Integer;
  DataPointer: PByte;
 // arg1:u_long;
begin
  sendr:=false;
  DataPointer := Buffer;
  Position := 0;
  BytesToWrite := 0;
//  arg1:=1;
// IOCtlSocket (SocketHandle,FIONBIO,arg1);
  while (Position < DataSize) do
  begin
    BytesLeftToWrite := DataSize - Position;
    if (BytesLeftToWrite > 0) then
    begin
      if BytesLeftToWrite > 2048 then
        BytesToWrite := 2048
      else
        BytesToWrite := BytesLeftToWrite;
    end;

    AmountSent := send(ClientHandle, DataPointer^, BytesToWrite, 0);

    if (AmountSent = SOCKET_ERROR) then
    begin
      Result := False;
      Exit;
    end;

    Inc(DataPointer, AmountSent);
    Position := Position + AmountSent;
  end;
//  arg1:=0;
// IOCtlSocket (SocketHandle,FIONBIO,arg1);
  Result := True;
  sendr:=true;
end;

Создание сокета:
Код:
function WlanStartServer() : Boolean;
var
  arg: Integer;
  IPs: String;
begin
  Result := False;

  WSAStartup($101, WSADataStruct);

  // Create socket
  SocketHandle := Winsock.socket(PF_INET, SOCK_STREAM, 0);

  if (SocketHandle = INVALID_SOCKET) then
  begin
    MessageDlg('socket() failed!', mtError, [mbOK], -1);
    Exit;
  end;

  // Bind socket
  SockAddr.sin_family := AF_INET;
  SockAddr.sin_addr.S_addr := INADDR_ANY;
  SockAddr.sin_port := htons(17584);

  if (bind(SocketHandle, SockAddr, sizeof(SockAddr)) = SOCKET_ERROR) then
  begin
    MessageDlg('The port used by the PSPdisp server is in use. Probably another instance is already running.', mtError, [mbOK], -1);
    //MessageDlg('bind() failed!', mtError, [mbOK], -1);
    Exit;
  end;

  // Start listening, only accept 1 client (0 clients in backlog)
  if (listen(SocketHandle, 1) = SOCKET_ERROR) then
  begin
    MessageDlg('listen() failed!', mtError, [mbOK], -1);
    Exit;
  end;

  arg := 1000;
  setsockopt(SocketHandle, SOL_SOCKET, SO_RCVTIMEO, @arg, sizeof(arg));
  setsockopt(SocketHandle, SOL_SOCKET, SO_SNDTIMEO, @arg, sizeof(arg));

  // Show "Server started" message
  IPs := GETAllIPAddresses();
  MainForm.OptionsWlanAddress.Caption := Ips;


  if MainForm.OptionsWlanNotifyStart.Checked then
    MainForm.ShowBalloonHint('PSPdisp: Server started', 'Please connect your PSP to the following IP address:' + #10 + Ips, bfInfo);

  Result := True;
end;
Ответить с цитированием
  #2  
Старый 28.06.2010, 14:06
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

send Function:
Цитата:
If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in nonblocking mode.
http://msdn.microsoft.com/en-us/libr...49(VS.85).aspx
Цитата:
Send блокирует нить, если в выходном буфере сокета недостаточно места, чтобы скопировать туда переданную информацию.
http://www.delphikingdom.com/asp/vie...alogid=1021#11

попробуй setsockopt с SO_SNDBUF

Последний раз редактировалось NumLock, 28.06.2010 в 14:28.
Ответить с цитированием
  #3  
Старый 28.06.2010, 14:57
Master255 Master255 вне форума
Прохожий
 
Регистрация: 28.06.2010
Сообщения: 8
Репутация: 10
По умолчанию

Попробовал. Стало только хуже...Звук чаще стал заикаться. Поэксперементировал. По подставлял туда разные числа...даже 1048560 ни к чему не приводит. Заикания всё там же и всё так же...
Ветка, которая отправляет данные в реалтайм приоритете. Но когда я начинаю например распаковывать винрар она замедляет свою работу и звук начинает заикаться.
Я выяснил что заикание происходит на функции send. Т.е. приоритет выполнения этой функции мал.. Как можно его повысить до максимума??

Может нужно использовать высокоприоритетные данные (out-of-band data)?? Скажите хотя бы куда копать???

Программа загружает комп на 1-2%. Приоритет программы реалтайм. Приоритет ветки тоже максимальный. Однако где-то ещё нужно выставить приоритет. Ведь если я не загружаю программ, то заиканий не возникает!

Последний раз редактировалось Master255, 28.06.2010 в 15:28.
Ответить с цитированием
  #4  
Старый 29.06.2010, 08:32
Rat Rat вне форума
Активный
 
Регистрация: 12.09.2008
Сообщения: 391
Репутация: 6078
По умолчанию

А зачем давать программе реалтайм, если всё равно сама винда занимается отсылкой? Может наоборот надо понизить?
Ответить с цитированием
  #5  
Старый 29.06.2010, 12:28
Master255 Master255 вне форума
Прохожий
 
Регистрация: 28.06.2010
Сообщения: 8
Репутация: 10
По умолчанию

а винде нельзя задать приоритет на отсылку???
Ответить с цитированием
  #6  
Старый 29.06.2010, 13:16
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

имхо, скорость интернет несоизмеримо меньше быстродействия компьютера, если, конечно эти показатели можно как-то сравнивать)

у меня вообще, скажем так, противоположная проблема: функция send() возвращается сразу же, без ожидания реальной отправки данных в сеть (я не о подтверждении приема, а о самой отправке), хотя в писании сказано другое: будет блокироваться, если размера внутреннего буфера не хватает. а его естественно не должно хватать. а мне это важно, т.к. у меня стоит progressbar в цикле, который в этой ситуации, естественно, пробегает моментом. сама же отправка данных в сеть идет в фоновом режиме и одному (?) известно, когда она закончится. это так работает на Windows 7, на XP же функция send() как и положено блокируется на время отправки пакета и progressbar показывает реальный процесс передачи данных.

Последний раз редактировалось NumLock, 29.06.2010 в 13:23.
Ответить с цитированием
  #7  
Старый 29.06.2010, 20:19
Master255 Master255 вне форума
Прохожий
 
Регистрация: 28.06.2010
Сообщения: 8
Репутация: 10
По умолчанию

хм...у меня семёрка 64бит ултимейт. всё работает прекрасно. попробуй вручную флаг блокировки поставить?
Я если этим флагом убираю блокировку, то у меня ваще каша получается...т.к. 2 сенда используется. для хеадера и данных. Они друк на друга накладываются и медленно отправляются.
Я уже замерил время на которое задержка происходит в функции send это примерно 150миллисекунд при самом загруженном компе, так что даже мышка струдом двигается... Поговорю с разработчиком. Думаю на время передачи звука нужно увеличивать буфер передачи...иначе никак...программа то многофункциональная...
Ответить с цитированием
  #8  
Старый 29.06.2010, 20:48
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

да пробовал. я блокируемый, не блокируемый, overlapped сокеты пробовал, wininet пробовал - ничего не помогает: цикл прокручивается мгновенно, весь этот объем попадает в NonPagedPool и отпарвка идет в фоне, которую в принципе могу отслеживать сниффером, но с ним опять загвоздка: для его работы нужен запуск программы под администратором, что тожа не приемлемо.
а антивирь не пробовал отключать?
Ответить с цитированием
  #9  
Старый 29.06.2010, 21:11
Master255 Master255 вне форума
Прохожий
 
Регистрация: 28.06.2010
Сообщения: 8
Репутация: 10
По умолчанию

пробовал...точно не в нём дело...send задерживает windows. три процедуры=150*3 примерно равно 400мс...и если учесть что надо 10 циклов что бы передать аудиобуфер, вот и получается sometimes 4000мс...4 секунды простоя...думаю если бы у меня тормозили остальные программы бы из за передачи данных, то дискомфорта я не испытывал бы...загружает процессор всё это на 1-2%
Ответить с цитированием
  #10  
Старый 01.07.2010, 04:01
Master255 Master255 вне форума
Прохожий
 
Регистрация: 28.06.2010
Сообщения: 8
Репутация: 10
По умолчанию

решил проблему увеличением буферов передачи данных оператором setsockopt.
И использованием не блокирующих буферов (IOCtlSocket (SocketHandle,FIONBIO,arg1). Всё просто летает!
Ответить с цитированием
Ответ


Delphi Sources

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

Расширенный поиск
Опции просмотра

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

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:24.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter