1

私がやろうとしているのは、SIPメッセージをリッスンするSIPクライアントを実装することです。サーバー上でSIPクライアントを実行し192.168.0.246、SIPサーバーが実行され192.168.2.40ています。下のスクリーンショットを見てください。

ここに画像の説明を入力

でクライアント コードを実行しているサーバーのトレース ファイルです192.168.0.246。ご覧のとおり、サーバーは192.168.2.40SIP/SDP プロトコルを使用してメッセージを受信しますが、192.168.0.246 で実行されているクライアント プログラムが UDP プロトコルを使用して 192.168.2.40 にメッセージを送り返すと、正しい UDP プロトコルとして表示されます。しかし、192.168 からの応答はありません。この後2.40。だから私はそれが次のように示されているプロトコルと関係があると仮定しています.だから私UDPが儀式なら、それをSIP / SDPに取得する必要があります.

したがって、私の質問は、この UDP を SIP/SDP に変更する方法です。

そして、ここに私のPHPコードがあります:

<?php

//Reduce errors
error_reporting(~E_WARNING);

//Create a UDP socket
if(!($sock = socket_create(AF_INET, SOCK_DGRAM, 0)))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Couldn't create socket: [$errorcode] $errormsg \n");
}

echo "Socket created \n";

// Bind the source address
if( !socket_bind($sock, "192.168.0.246" , 5060) )
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Could not bind socket : [$errorcode] $errormsg \n");
}

echo "Socket bind OK \n";

//Do some communication, this loop can handle multiple clients

function GetBranchValue($message)
{
    $data = "";
    if(preg_match('/branch=.*/i', $message, $output))
        $data = explode("=",$output[0]);
    if(sizeOf($data)>1)
        return $data[1];
    else
        return "None";
}

function GetTag($message)
{
    $data = "";
    if(preg_match('/tag=.*/i',$message, $output))
        $data = explode("=", $output[0]);
    if(sizeOf($data)>1)
        return $data[1];
    else
        return "None";
}

function GetCallId($message)
{
    $data = "";
    if(preg_match('/Call-ID:.*/i', $message, $output))
        $data = explode(":",$output[0]);
    if(sizeOf($data)>1)
        return $data[1];
    else
        return "None";
}

function GetCSeq($message)
{ 
    $data = "";
    if(preg_match('/CSeq:.*/i', $message, $output))
    {
        $data = explode(":", $output[0]);
        $data = explode(" ",$data[1]);
    }
    if(sizeOf($data[1])>0)
        return $data[1];
    else
        return "None";
}

function CreateResponse($message)
{
    $msg = "SIP/2.0 302 Moved temporarily
Via:SIP/2.0/UDP 192.168.2.40:5060;branch=".GetBranchValue($message)."
From: <sip:+12012030008@192.168.2.40:5060>;tag=".GetTag($message)."
To:<sip:+17066458407@192.168.0.246:5060;user=phone>;tag=883069368-1363286882583
Call-ID:".GetCallId($message)."
CSeq:".GetCSeq($message)." INVITE
Contact:<sip:+17066458407@192.168.0.246:5060;user=phone>;q=0.5,<sip:+17066458407@192.168.0.246:5060;user=phone>;q=0.25
Content-Length:0";
    return $msg;
}

function Create300Response($message)
{
    $msg = "SIP/2.0 300 Multiple Choices
Via: SIP/2.0/UDP 192.168.2.40:5060;branch=".GetBranchValue($message)."
From: <sip:+12012030008@192.168.2.40:5060>;tag=".GetTag($message).";isup-oli;isup-oli=00
To:<sip:+17066458407@192.168.0.246:5060;user=phone>;tag=123
Contact: <sip: +17066458407@192.168.0.246:5060;dtg=16>
Contact: <sip: +17066458407@192.168.0.246:5060;dtg=16>
Contact: <sip: +17066458407@192.168.0.246:5060;dtg=16>
Contact: <sip: +17066458407@192.168.0.246:5060;dtg=16>";
    return $msg;
}

while(1)
{
    echo "Waiting for data ... \n";

    //Receive some data
    $r = socket_recvfrom($sock, $buf, 512, 0, $remote_ip, $remote_port);
    echo "$remote_ip : $remote_port -- " . $buf;
    file_put_contents("Log.txt","\n",FILE_APPEND);
    file_put_contents("Log.txt","Received Response------\n",FILE_APPEND);
    file_put_contents("Log.txt",$buf,FILE_APPEND);
    $respMessage = Create300Response($buf);
    //Send back the data to the client
    socket_sendto($sock, "OK " . $respMessage , 100 , 0 , $remote_ip , $remote_port);
    file_put_contents("Log.txt","\n",FILE_APPEND);
    file_put_contents("Log.txt","\n",FILE_APPEND);
    file_put_contents("Log.txt",$respMessage,FILE_APPEND);
}

socket_close($sock);
4

1 に答える 1

5
socket_sendto($sock, "OK " . $respMessage , 100 , 0 , $remote_ip , $remote_port);
//                    ^^ remove this

送信している は無効です。これは SIP プロトコル違反です。そのOK結果、Wireshark の組み込み SIP デコーダーはメッセージを有効な SIP パケットとして認識しません。

あなたはちょうどで応答する必要があります$respMessage

また、受信メッセージには適切なパーサーを使用し、送信メッセージの作成には適切なオブジェクト指向ライターを使用することを強くお勧めします。SIP は (不必要に言う人もいるかもしれませんが) 複雑なプロトコルです。リモートで有用であっても何でもできるエンドポイントを構築するには、抽出する情報の小さな塊以上のものを必要とします。

私のこの小さなライブラリは、パーサーの良いベースになるかもしれませHTTPSIP

于 2013-03-19T13:43:29.683 に答える