【SIP基础】SIP协议响应代码

SIP响应是由用户代理服务器(UAS)生成或由客户端生成来回应服务器请求的消息。它是一个正式的回复确认,以防止UAC重发请求。

  • 响应可能需要包含一些额外的头字段

  • SIP有六类响应

  • 1xx - 5xx是借由HTTP协议,而6xx是在SIP中介绍。

  • 1XX被认为是一个临时响应,其余的最终响应。

类 别描述动作
1xx信息用来只是呼叫完成前的状态,也被称为临时响应。
2xx   成功请求处理成功。如果是INVITE消息的,应回应ACK消息;否则表示停止重发请求。
3xx重定向服务器返回可用的位置。客户端应该重试请求到另一个服务器上。
4xx客户端错误请求失败,由于客户端的错误。客户端可以根据响应修改请求并重试。
5xx服务器故障请求失败,由于服务器的错误。请求可以向另一台服务器重试。
6xx全局失败请求失败。是全局性错误,该请求不应该向其他服务器再次尝试。

信息(1xx)

信息(1xx)响应用于指示呼叫过程。通常情况下,响应是端对端(除100尝试)。信息(1xx)的响应的主要目的是阻止INVITE请求的重发。

信息响应包括以下响应:

100 Trying (尝试)

  • 这种特殊的情况下的响应仅仅是一个逐跳请求。

  • 它永远不会转发,不得包含消息体。

  • 它被用于避免INVITE请求的重传。

180 Ringing (响铃)

  • 此响应被用来指示用户代理已经接收到INVITE消息,并且正在电话振铃。

181 Call is Being Forwarded (呼叫被转发)

  • 此响应用于指示该呼叫已被转发到另一端。

  • 当主叫需要此响应消息时才被发送。

  • 此响应告诉主叫,由于转发操作会导致应答时间变长。

182 Call Queued (呼叫队列)

  • 此响应被用来指示该INVITE消息已经接收到,并且将在队列进行处理。

183 Session Progress (会话进度)

  • 它指示本次会话的进度信息可以存在于消息主体或媒体流中。

  • 不像100 Trying的尝试响应,183是端对端的响应,并且会实际性的建立起一个对话。

  • 一个典型的应用环境是让UAC通过落地网关进入PSTN网络,并让主叫听到手机铃声,或忙音,或通话录音的通知音。(此消息也是电话铃音透传的关键)

成功(2xx)

此类响应是用于指示一个请求已被接受。它包括以下响应:

200 OK

  • 200 OK用于接受会话邀请。
  • 它表示成功完成的请求或接受请求。

202 Accepted (接受)

  • 表示该UAS已经接收并理解了请求,但该请求可能没有被授权或正在由服务器处理。

  • 它是常用来响应SUBSCRIBE消息,REFER消息。

重定向(3xx)

通常这类响应是由重定向服务器发送,来响应INVITE消息的。它们也被称为重定向类响应。它包括以下响应:

300 Multiple Choices (多重选择)

  • 它包含多个联系人的报头字段,说明该位置服务器返回多个可能的位置,并在Request-URI中用多个SIP URI表示。

301 Moved Permanently (永久移动)

  • 这种重定向响应在Contact头字段中包含着被叫方的新的永久性的URI。

  • 位置地址可以被保存,并在以后的INVITE请求中使用。

302 Moved Temporarily (临时移动)

  • 该响应包含一个URI,该URI是当前有效的,但不是永久的。

  • 也就是该URI位置地址在指定的特殊时间内是有效的 。

305 Use Proxy (使用代理)

  • 这个响应包含一个URI,该URI指向具有对呼叫方有认证信息的代理服务器。

  • 这种响应可以由发出来电的UAS代理服务器发送。

380 Alternative Service (可替代服务)

  • 这个响应返回一个URI,该URI指示被叫方希望的服务类型。

  • 例如,一个通话可以被重新定向到一个语音信箱的服务。

客户端错误(4xx)

客户端错误的响应表明,由于UAC端的一些错误使得请求不能得到满足。响应代码通常由UAS来发送。客户端在接收到出错消息时,应该基于该响应的描述进行修改并重新发送。下面讨论的是一些重要的客户端错误的响应。

400 Bad Request (错误的请求)

  • 这表明该请求不被服务器理解。

  • 请求可能是缺少必要的头字段,例如To, From, Call-ID, 或 CSeq。

401 Unauthorized (未经授权)

  • 说明该请求要求用户进行认证。

  • 401 Unauthorized 通常回应的是注册请求,由代理服务器发送。

  • 该响应包含WWW-Authenticate身份验证头字段,该字段表明从主叫那里获得正确的凭据请求。

  • 随后,REGISTER将重发,并包含着用户的正确的凭据。
    401_unauthorized.jpg

403 Forbidden (禁止)

  • 403 Forbidden 说明代理服务器已经理解请求,并正确匹配请求,但不能提供该请求的服务。

  • 这种响应在需要授权时不能使用。

404 Not Found (未找到)

  • 404 Not Found表明在服务器中没有找到该请求URI标识中的SIP URI用户。

405 Method Not Allowed (不允许的方法)

  • 说明服务器或用户代理已收到并理解该请求,但不能执行该请求。

  • 例如:当注册请求被发送到用户代理端时,用户代理可响应405。

  • 在消息头中,Allow 域是必需的,它告诉UAC什么方法是可以接受的。

406 Not Acceptable (不接受)

  • 该响应说明不能按照该请求消息中的规定来处理。

  • 在请求中的Accept头域中没有包含UAS支持的任何选项。

407 Proxy Authentication Required (需要代理身份验证)

  • 由代理服务器发送该请求说明UAC必须首先验证自身的请求后才可以被处理。

  • 响应消息的Proxy-Authenticate头字段中应包含所需凭据的类型信息。

  • 该请求可以被重新提交,并在Proxy-Authenticate头字段中包含正确的凭据。

408 Request Timeout (请求超时)

  • 当响应时间超过INVITE请求的Expires头域字段中指定的时间段时,该响应被发送。

  • 它可以由代理服务器或用户代理发送。

  • 该请求可以在任何时候由UAC重试。

422 Session Timer Interval Too Small (会话定时器间隔太小)

  • 该响应被用来处理拒绝含有Session-Expires头字段的请求。

  • 允许的最小间隔被表示在所请求的Min-SE头字段中。

  • 主叫方可以重新尝试,当没有会话Expires头字段或间隔时间值大于或等于规定的最小值时。

423 Interval Too Brief (间隔太短)

  • 该响应说明在请求中设置的资源刷新时间(或者有效时间)过短,可以用于代理服务器来拒绝那些Contact头域有效期过短的注册请求。

  • 该响应必须包含Min-Expires头域并指出最小有效期,该注册者应该接受并修改。

480 Temporarily Unavailable (暂时不可用)

  • 该响应说明请求已正确到达被叫方,但因被叫方有一些暂时不可用的原因而拒绝。

  • 该响应应包含一个Retry-After头,表明何时请求可以得到满足。

481 Dialog/Transaction Does Not Exist (对话/事务不存在)

  • 该响应说明UAS接收到请求,但是没有和现存的对话或者事务匹配。

483 Too Many Hops (太多的跳数)

  • 此响应说明请求已被转发的次数已达到上限,该判断由请求的Max-Forwards头来设置。

  • 请求中Max-Forward:0,即数值为0来表示达到最大转发。

486 Busy Here (忙,占线)

  • 该响应说明用户代理正在忙,不能接受呼叫。

487 Request Terminated (请求终止)

  • 该响应会被发送,当用户CANCEL来结束INVITE请求时。

  • 200 OK消息用来确认CANCEL消息,用487 Request Terminated来取消INVITE请求。

服务器故障 (5xx)

此类响应说明因服务器中的错误而不能处理发来的请求。显然对有效的请求服务器也无法完成。此类响应可包含一个Retry-After头字段,用来表明可以在其它地址进行重试,因为没有在请求中表明请求的错误,所以智能采用重试方法。一些重要的服务器故障响应如下。

500 Server Internal Error (服务器内部错误)

  • 500表示服务器发生了某种错误,从而不能处理请求。

  • 它是一种服务器故障,指示客户端过一段时间后可以再次重试请求。

501 Not Implemented (未实现)

  • 它表明服务器无法执行,因为它不支持处理该请求。

  • 该响应被用来拒绝含有未知方法的请求。

502 Bad Gateway (错误的网关)

  • 如果服务器作为网关或者代理存在,从下行服务器上接收到了一个非法的应答(这个应答对应的请求是本服务器为了完成请求而转发给下行服务器的)

  • 这表明有其他的一些网络问题使请求不能被处理。

503 Service Unavailable (暂停服务)

  • 该响应说明所请求的服务是暂时不可用。

  • 服务器可以在应答中增加一个Retry-After来让客户端重试这个请求。客户端在Retry-After头字段期满之后才能进行重试。

504 Gateway Timeout (网关超时)

  • 该响应说明服务器在一个外部服务器上没有收到一个及时的应答。这个外部服务器是本服务器用来访问处理这个请求所需要的。如果从上行服务器上收到的请求中的Expires头域超时,那么应当返回一个408(Request TimeOut)错误。

  • 它是一个服务器错误类响应,是因为服务器访问SIP网络以外的资源未能得到响应引起的。

505 Version Not Supported (版本不支持)

  • 该响应说明服务器不支持对应的SIP版本。

  • 目前SIP2.0版是唯一的实现版本。

513 Message Too Large (消息过大)

  • 此响应说明无法处理请求,因为消息长度超过了处理的长度。

580 Preconditions Failure (前提条件失败)

  • 此响应说明SDP中需要的前提条件不能得到满足而拒绝请求。

全局错误 (6xx)

此响应类表示服务器知道该请求无论怎样尝试都将会失败,所以,该请求不应该被发送到其他地方。

这意味这服务器给特定用户有一个最终的信息,并不只是在Request-URI的特定实例有最终信息。 一些重要的响应的如下:

600 Busy Everywhere (任意占线)

  • 只有当终端系统知道没有其他终端节点(比如语音邮箱系统)能 够访问到这个用户的时候才能使用这个应答。否则应当返回一个486(Busy Here)的应答。

603 Decline (拒绝)

  • 该响应表明被叫方占线,或者干脆不希望接通呼叫。

604 Does Not Exist Anywhere (不存在任何地方)

  • 该响应类似于404未找到的响应,但表示在Request-URI中的用户不能在任何地方找到。

  • 该反应应该仅由具有访问所有相关用户信息的服务器发送。

606 Not Acceptable (不接受)

  • 该响应说明成功联系到一个UA,但是会话描述的一些部分比如请求的媒体,带宽,或者地址类型不被接收。

  • 该响应意味着用户希望通讯,但是不能充分支持会话描述。

  • 可以在Warning头域中包含一个原因列表,用于解释为何会话描述不能被支持。

  • 3
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: SIP(Session Initiation Protocol)是一种用于建立、修改和终止多媒体会话的信令协议。下面是使用C语言编写的基本SIP协议代码的示例: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define MAX_BUFFER_SIZE 1024 #define SIP_PORT 5060 int main() { int sockfd; struct sockaddr_in server_addr; char buffer[MAX_BUFFER_SIZE]; // 创建UDP套接字 sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("Socket creation failed"); exit(EXIT_FAILURE); } // 初始化服务器地址结构 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SIP_PORT); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 服务器IP地址 // 将套接字绑定到服务器地址 if (bind(sockfd, (const struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("Socket binding failed"); exit(EXIT_FAILURE); } printf("SIP Server listening on port %d\n", SIP_PORT); while (1) { struct sockaddr_in client_addr; unsigned int addr_len = sizeof(client_addr); // 接收来自客户端的请求 ssize_t received_bytes = recvfrom(sockfd, (char*)buffer, MAX_BUFFER_SIZE, 0, (struct sockaddr*)&client_addr, &addr_len); if (received_bytes < 0) { perror("Error in receiving request"); exit(EXIT_FAILURE); } printf("Received request from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); printf("Request message:\n%s\n", buffer); // 在此处你可以解析SIP请求并进行相应的处理 // 发送响应给客户端 const char* response = "SIP response"; ssize_t sent_bytes = sendto(sockfd, response, strlen(response), 0, (struct sockaddr*)&client_addr, addr_len); if (sent_bytes < 0) { perror("Error in sending response"); exit(EXIT_FAILURE); } printf("Response sent to %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); } // 关闭套接字 close(sockfd); return 0; } ``` 上述代码使用C语言实现了一个简单的SIP服务器,它监听5060端口的UDP请求。它首先创建一个UDP套接字,然后绑定到服务器地址上。接着通过`recvfrom()`函数接收来自客户端的SIP请求,并将请求内容打印到控制台上。在此处你可以对请求进行解析和处理。最后,通过`sendto()`函数将响应消息发送回客户端,并将响应信息打印到控制台。 请注意,这只是一个简单的示例代码,实际的SIP服务器需要更复杂的逻辑和功能来处理不同类型的请求、呼叫流程管理等等。 ### 回答2: SIP(Session Initiation Protocol)协议是一种用于建立、修改和终止多媒体会话的通信协议。在C语言中,我们可以使用标准的网络编程库来实现SIP协议的源代码。 以下是一个简单的SIP协议的C语言源代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define MAX_BUFFER_SIZE 1024 int main() { int socket_fd; struct sockaddr_in server_addr; char buffer[MAX_BUFFER_SIZE]; // 创建TCP socket socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 0) { perror("Socket creation failed.\n"); exit(EXIT_FAILURE); } // 设置服务器地址 server_addr.sin_family = AF_INET; server_addr.sin_port = htons(5060); // SIP默认端口号 server_addr.sin_addr.s_addr = inet_addr("192.168.0.1"); // 服务器IP地址 // 连接服务器 if (connect(socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("Connection failed.\n"); exit(EXIT_FAILURE); } // 发送SIP请求 snprintf(buffer, MAX_BUFFER_SIZE, "REGISTER sip:192.168.0.1 SIP/2.0\r\n" "Via: SIP/2.0/TCP 192.168.0.2:5060\r\n" "From: Alice <sip:alice@192.168.0.2>;tag=1234\r\n" "To: Bob <sip:bob@192.168.0.1>\r\n" "Call-ID: 4321@192.168.0.2\r\n" "CSeq: 1 REGISTER\r\n" "Contact: <sip:alice@192.168.0.2>\r\n" "Content-Length: 0\r\n\r\n"); if (send(socket_fd, buffer, strlen(buffer), 0) < 0) { perror("Send failed.\n"); exit(EXIT_FAILURE); } // 接收服务器响应 memset(buffer, 0, MAX_BUFFER_SIZE); if (recv(socket_fd, buffer, MAX_BUFFER_SIZE, 0) < 0) { perror("Receive failed.\n"); exit(EXIT_FAILURE); } // 打印服务器响应 printf("Received response:\n%s\n", buffer); // 关闭socket连接 close(socket_fd); return 0; } ``` 上述代码使用C语言中的Socket编程库创建一个TCP socket,并与指定的SIP服务器建立连接。然后,通过send函数发送一个SIP REGISTER请求,并通过recv函数接收服务器的响应。最后,打印服务器的响应,并关闭socket连接。 请注意,上述代码只是一个简单的示例,仅仅发送了一个REGISTER请求,并打印了服务器的响应。实际情况中,SIP协议的实现会更加复杂,需要处理更多的请求和响应消息,并实现SIP协议的各种功能。 ### 回答3: SIP(会话初始协议)是一种用于建立、修改和终止多媒体会话的应用层协议。它是一个基于文本的协议,使用类似HTTP的请求和响应格式。 下面是一个简单的使用C语言实现的SIP协议代码示例: ```c #include <stdio.h> // 定义SIP请求方法枚举类型 enum SIPRequestMethod { INVITE, // 邀请 ACK, // 应答确认 BYE, // 结束会话 CANCEL, // 取消邀请 REGISTER // 注册 }; // 定义SIP响应状态码枚举类型 enum SIPResponseStatus { OK = 200, // 成功 NOT_FOUND = 404, // 未找到 INTERNAL_SERVER_ERROR // 内部服务器错误 }; // 定义SIP请求结构体 struct SIPRequest { enum SIPRequestMethod method; // 请求方法 char* uri; // 统一资源标识符 }; // 定义SIP响应结构体 struct SIPResponse { enum SIPResponseStatus status; // 响应状态码 char* message; // 响应消息 }; // 处理SIP请求的函数 struct SIPResponse processSIPRequest(struct SIPRequest request) { struct SIPResponse response; // 根据请求方法执行相应的处理逻辑 switch (request.method) { case INVITE: // 处理邀请请求 response.status = OK; response.message = "Invite successful"; break; case ACK: // 处理确认应答 response.status = OK; response.message = "Ack successful"; break; case BYE: // 处理结束会话请求 response.status = OK; response.message = "Bye successful"; break; case CANCEL: // 处理取消邀请请求 response.status = OK; response.message = "Cancel successful"; break; case REGISTER: // 处理注册请求 response.status = OK; response.message = "Register successful"; break; } return response; } int main() { // 创建一个SIP请求并设置请求方法和URI struct SIPRequest request; request.method = INVITE; request.uri = "sip:example.com"; // 处理SIP请求并获取响应 struct SIPResponse response = processSIPRequest(request); // 打印响应状态码和消息 printf("Response status: %d\n", response.status); printf("Response message: %s\n", response.message); return 0; } ``` 这个示例展示了一个简单的SIP协议的C语言源代码,其中包括定义了SIP请求和响应的结构体,以及处理SIP请求的函数。在主函数中,创建了一个SIP请求并设置了请求方法和URI,然后调用处理SIP请求的函数并打印出其返回的响应状态码和消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值