我要做的是实现一个侦听SIP消息的SIP客户端。所以我在服务器192.168.0.246
上运行了SIP客户端,而SIP服务器正在192.168.2.40
上运行。现在看看下面的屏幕截图。
它是在192.168.0.246
上运行客户端代码的服务器的跟踪文件。您可以看到服务器使用SIP / SDP协议从192.168.2.40
接收消息,但是当运行在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);
答案 0 :(得分:5)
socket_sendto($sock, "OK " . $respMessage , 100 , 0 , $remote_ip , $remote_port);
// ^^ remove this
您发送的OK
无效,违反了SIP协议,因此Wireshark中的内置SIP解码器无法将该消息识别为有效的SIP数据包。
您应该只是回复$respMessage
此外,我强烈建议您使用适当的解析器来传入消息,并使用适当的面向对象的编写器来构造传出消息。 SIP是一种(有些人可能会说是不必要的)复杂的协议,你需要的不仅仅是你提取的小块信息,而是建立一个甚至可以做任何远程有用的端点。
我的This small library可能会为您的解析器提供一个良好的基础,而this one如果用HTTP
替换SIP
,{{3}}几乎完全符合您的要求。