我目前正在研究SIP示例应用程序。SIP注册问题
我想在Unix上使用基于C的Socket编程进行注册。我已经成功地获得了PJSIP的注册,但是当我使用正常的套接字编程发送相同的参数时,我无法从服务器收到任何响应。
这里是源代码:
char *server = (char *)serverAddress; // First arg: server address/name
char *echoString = "Request msg REGISTER/cseq=46476 (tdta0x8857200)\r\nREGISTER sip:DOMAIN_NAME SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.1.120:51648;rport;branch=z9hG4bKPjwEt4VvIVdjIJKRmEJbkidYDAu-zQbIqv\r\nMax-Forwards: 70\r\nFrom: <sip:[email protected]_NAME>;tag=epCBN7JXsQE1nnI5d5SOZe9a5ujRyI67\r\nTo: <sip:[email protected]_NAME>\r\nCall-ID: .5yYCqh2jEYdy5T4kxhzxwDYEkCO1XlD\r\nCSeq: 46476 REGISTER\r\nContact: <sip:[email protected]:51648;ob>\r\nExpires: 300\r\nAllow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS\r\nAuthorization: Digest username=\"USER_NAME\", realm=\"asterisk\", nonce=\"3b63254c\", uri=\"sip:DOMAIN_NAME\", response=\"9e8fc78829d143a58fba5a79f6ad44fd\", algorithm=MD5\r\nContent-Length: 0";
size_t echoStringLen = strlen(echoString);
// Third arg (optional): server port/service
char *servPort = (char *)service;
// Tell the system what kind(s) of address info we want
struct addrinfo addrCriteria; // Criteria for address match
memset(&addrCriteria, 0, sizeof(addrCriteria)); // Zero out structure
addrCriteria.ai_family = AF_UNSPEC; // For the following fields, a zero value means
// Any address family "don't care"
addrCriteria.ai_socktype = SOCK_DGRAM; // Only datagram sockets
addrCriteria.ai_protocol = IPPROTO_UDP; // Only UDP protocol
// Get address(es)
struct addrinfo *servAddr; // List of server addresses
int rtnVal = getaddrinfo(server, servPort, &addrCriteria, &servAddr);
if (rtnVal != 0)
DieWithUserMessage("getaddrinfo() failed", gai_strerror(rtnVal));
// Create a datagram/UDP socket
int sock = socket(servAddr->ai_family, servAddr->ai_socktype,
servAddr->ai_protocol); // Socket descriptor for client
if (sock < 0)
DieWithSystemMessage("socket() failed");
// Send the string to the server
ssize_t numBytes = sendto(sock, echoString, echoStringLen, 0,
servAddr->ai_addr, servAddr->ai_addrlen);
if (numBytes < 0)
DieWithSystemMessage("sendto() failed");
else if (numBytes != echoStringLen)
DieWithUserMessage("sendto() error", "sent unexpected number of bytes");
// Receive a response
struct sockaddr_storage fromAddr; // Source address of server
// Set length of from address structure (in-out parameter)
socklen_t fromAddrLen = sizeof(fromAddr);
char buffer[100 + 1]; // I/O buffer
numBytes = recvfrom(sock, buffer, 100, 0,
(struct sockaddr *) &fromAddr, &fromAddrLen);
if (numBytes < 0)
DieWithSystemMessage("recvfrom() failed");
else if (numBytes != 100)
DieWithUserMessage("recvfrom() error", "received unexpected number of bytes");
// Verify reception from expected source
int value = SockAddrsEqual(servAddr->ai_addr, (struct sockaddr *) &fromAddr);
if (value == 0)
DieWithUserMessage("recvfrom()", "received a packet from unknown source");
freeaddrinfo(servAddr);
buffer[echoStringLen] = '\0'; // Null-terminate received data
printf("Received: %s\n", buffer); // Print the echoed string
close(sock);
exit(0);
当我试图调试代码,然后断点会从recvfrom的方法调用消失如下。
numBytes = recvfrom(sock, buffer, 100, 0, (struct sockaddr *) &fromAddr, &fromAddrLen);
在此先感谢您的合作。
“断点消失”是什么意思?你的程序崩溃了吗?至于事情的SIP方面,您正在使用的方法将无法正常工作,因为您试图重播现有的REGISTER请求。服务器会因多种原因拒绝重播请求,包括重复的SIP事务和使用陈旧的随机数。 – sipwiz 2012-02-13 11:51:42
该应用程序既不崩溃也不前进。看来,该应用程序正在等待服务器响应recv方法。但使用其他软电话,我已经能够注册很多次了。由于SIP注册在一定的时间间隔内有效,并且在此之后它正在取消注册。为了维护会话,我们需要重新注册SIP服务器。 – 2012-02-13 12:01:36