Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.02.2018, 12:14   #1
slavak78
Новичок
Джуниор
 
Регистрация: 01.05.2010
Сообщений: 3
По умолчанию Вопрос по SIP-телефонии

Здравствуйте, помогите решить следующую проблему.

С вопросом регистрации на SIP-сервере все в порядке. Посылаю REGISTER, приходит ответ 401 not authorized, отправляю вновь REGISTER с "Authorization: Digest...". Приходит ответ 200 и все, больше никаких пакетов не приходит, пока не начинаю номер набирать - вот здесь то и начинается проблема.
Посылаю INVITE уже в потоке:

Код:
while not terminated do begin
answer := form1.GetAnswer(FSocket);
и т.д.
Содержание GetAnswer:

Код:
function TForm1.GetAnswer(FSocket:TSocket):string;
var
  Buffer : array[0..1500] of Byte; // Буфер для получения сообщения. Размер равен максимальному размеру UDP-дейтаграммы.
  RecvAddr : TSockAddr; // Адрес, с которого пришло сообщение
  RecvLen, AddrLen : integer;
  paket : string;
begin
  // на каждой итерации цикла читается одна дейтаграмма
    AddrLen := SizeOf(RecvAddr);
    // Получаем дейтаграмму
    RecvLen := recvfrom(FSocket, Buffer[1], sizeof(Buffer), 0, RecvAddr, AddrLen);
    // если получаем ошибку при вызове recvfrom - завершаем работу нити.
    if RecvLen < 0 then
    begin
      Result := '';
    end;
    SetLength(paket, RecvLen); // Устанавливаем нужный размер строки
    // и копируем в неё дейтаграмму из буфера
    if RecvLen > 0 then
      move(Buffer, paket[1], RecvLen);
      if(paket<>'') then
    Result := paket;
end;
Так вот, после INVITE вновь приходит 401 not authorized, авторизуюсь.
Отправляю ACK. Все, телефоны звонят.
Далее, допустим, абонент отклонил звонок, не беря трубку. В том же потоке обрабатываю отклонение звонка.

Код:
...
ok:=copy(answer,2,11);
...
if(ok='SIP/2.0 486') then begin
terminate;
end;
...
После terminate поток приравниваю к nil.
Как бы все хорошо, звонок завершился.

Теперь допустим меня снова приспичило кому то позвонить.
Вновь thread запускаю, и что я вижу, опять ответ от сервера 486 Busy Here!!!

Такое впечатление, что не все пакеты от сервера я прочитал.
Да кстати, при создании сокета пишу:

Код:
setsockopt(fSendSocket,SOL_SOCKET,SO_RCVTIMEO,@Option,sizeof(Option));
Для того, чтобы все таки дождаться ответа от recvfrom.

Возможные решения:
1. Не до конца понимаю порядок запросов.
2. Убивать сокет и создавать новый.

Помогите, пожалуйста, начальство уже требует.
slavak78 вне форума Ответить с цитированием
Старый 19.02.2018, 09:54   #2
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Цитата:
Buffer : array[0..1500] of Byte; // Буфер для получения сообщения. Размер равен максимальному размеру UDP-дейтаграммы.
Теоретически, максимальный размер поля - 65535 байт для UDP-дейтаграммы (8 байт на заголовок и 65527 на данные). Минимальная длина равна длине заголовка - 8 байт.
попробуйте увеличить буфер
Buffer : array[0..$FFFF] of Byte

Но лучше прием сделать в stream чтобы не терять данные примерно так

Код:
из потока
var
answerStream: TStringStream;
begin
answerStream:= TStringStream.create(''); 
try
while not terminated do 
begin
answerStream:= TStringStream(GetAnswer(Socket));
if Pos('SIP/2.0 486', answerStream.DataString) <> 0 then 
terminate;
end;
...
finally
StringStream.free;
end;
end;

function TForm1.GetAnswer(FSocket:TSocket): TStream;
var
  Buffer : array[0..1023] of Byte; 
  RecvAddr : TSockAddr;
  RecvLen, AddrLen : integer;
begin
    AddrLen := SizeOf(RecvAddr);
    // Получаем дейтаграмму
    RecvLen := recvfrom(FSocket, Pointer(Buffer)^, sizeof(Buffer), 0, RecvAddr, AddrLen);
    if RecvLen > 0 then
    //записываем все данные в stream
    result.Write(Pointer(Buffer)^, RecvLen);
 end;

Последний раз редактировалось Aliens_wolfs; 20.02.2018 в 09:30.
Aliens_wolfs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Интеграция SIP-телефонии на сайт. (Сервисы с SIP-телефонией) Mr_freeman PHP 12 18.08.2015 17:50
Программа ip-телефонии Utkin Софт 11 17.02.2015 00:05
Обработка SIP телефонии. Возможно ли? Dozent Работа с сетью в Delphi 19 11.01.2013 10:55
Работа с SIP RuVarez Работа с сетью в Delphi 0 04.11.2011 22:49