GB/T28181平台C++实现学习笔记2:libosip2与libexosip2编译
文章目录
HelloWorld
我个人接触新的第三方库时,独立测试肯定要走helloworld,引用库头文件,调用库最基础的方法。
上代码:
#include "stdio.h"
#include <eXosip2/eXosip.h>
using namespace std;
int main(void)
{
int result;
// 初始化
eXosip_t *ctx = eXosip_malloc();
result = eXosip_init(ctx);
if (result != OSIP_SUCCESS)
{
printf("Can't initialize eXosip!\n");
return -1;
}
else
{
printf("eXosip_init successfully!\n");
}
// 结束
eXosip_quit(ctx);
ctx = nullptr;
printf("Hello World\n");
return 0;
}
运行结果
eXosip_init successfully!
Hello World
说明库配置没有问题,可以开搞了。
UAS 与UAC
UAC用于发起请求(request),而UAS用于产生响应(response)。
这两个概念不需要纠结,大部分情况下同一端既是UAS也是UAC。
请求中,发送(request)的是UAC,回复(response)就时UAS。
下面我们就做个简单的request – response的测试。
UAS(User Agent Server)用户代理服务器
初始化后可以设置一些参数,比如
eXosip_set_user_agent(ctx, "yjkhtddx/0.0.1");
然后加个端口监听:
int port = 15067;
result = eXosip_listen_addr(ctx, IPPROTO_UDP, NULL, port, AF_INET, 0);
if (result != OSIP_SUCCESS)
{
eXosip_quit(ctx);
fprintf(stderr, "could not initialize transport layer\n");
return -1;
}
然后加个事件处理
eXosip_event_t *evt = nullptr;
for (;;)
{
evt = eXosip_event_wait(ctx, 0, 50);
if (!evt)
{
printf("wait...\n");
continue;
}
switch (evt->type)
{
case EXOSIP_MESSAGE_NEW:
{
// if (osip_strcasecmp(minfo->sip_method, "MESSAGE") == 0)
if (osip_strcasecmp(evt->request->sip_method, "MESSAGE") == 0)
{
osip_message_t *answer = NULL;
eXosip_lock(ctx);
result = eXosip_message_build_answer(ctx, evt->tid, 200, &answer);
result = eXosip_message_send_answer(ctx, evt->tid, 200, answer);
eXosip_unlock(ctx);
}
break;
}
default:
{
printf("Unprocessed\n");
break;
}
}
eXosip_event_free(evt);
evt = nullptr;
}
完成,下面搞UAC
UAC(User Agent Client)用户代理客户端
初始化后开启监听
int port = 15068;
result = eXosip_listen_addr(ctx, IPPROTO_UDP, NULL, port, AF_INET, 0);
if (result != OSIP_SUCCESS)
{
eXosip_quit(ctx);
fprintf(stderr, "could not initialize transport layer\n");
return -1;
}
发送MESSAGE消息
bool quit = false;
while (!quit)
{
char messageCache[1024];
std::cout << "Please input the message: " << std::endl;
std::cin >> messageCache;
std::string message = std::string(messageCache);
std::cout << "send message: " << message << std::endl;
osip_message_t *osipMessagePtr = nullptr;
eXosip_lock(ctx);
char *source_call = "sip:client@127.0.0.1:15068";
char *dest_call = "sip:server@127.0.0.1:15067";
eXosip_message_build_request(ctx, &osipMessagePtr, "MESSAGE", dest_call, source_call, nullptr);
osip_message_set_body(osipMessagePtr, message.data(), message.length());
osip_message_set_content_type(osipMessagePtr, "text/plain");
eXosip_message_send_request(ctx, osipMessagePtr);
eXosip_unlock(ctx);
if (message == "quit")
{
break;
}
else
{
waitRES(ctx);
}
}
发送完等待回复
void waitRES(eXosip_t *ctx)
{
eXosip_event_t *evt = nullptr;
for (;;)
{
evt = eXosip_event_wait(ctx, 0, 50);
if (!evt)
{
printf("wait...\n");
continue;
}
if(evt->type == EXOSIP_MESSAGE_ANSWERED){
break;
}
eXosip_event_free(evt);
evt = nullptr;
}
}
完成,开始测试
测试结果
使用wireshark抓包结果
MESSAGE sip:server@127.0.0.1:15067 SIP/2.0
Via: SIP/2.0/UDP 127.0.0.1:15068;rport;branch=z9hG4bK644998637
From: <sip:client@127.0.0.1:15068>;tag=480476859
To: <sip:server@127.0.0.1:15067>
Call-ID: 1103854489
CSeq: 20 MESSAGE
Content-Type: text/plain
Max-Forwards: 70
User-Agent: yjkhtddx/0.0.1
Content-Length: 7
1234567
SIP/2.0 200 OK
Via: SIP/2.0/UDP 127.0.0.1:15068;rport=15068;branch=z9hG4bK644998637
From: <sip:client@127.0.0.1:15068>;tag=480476859
To: <sip:server@127.0.0.1:15067>;tag=1126161087
Call-ID: 1103854489
CSeq: 20 MESSAGE
User-Agent: yjkhtddx/0.0.1
Content-Length: 0
总结
实际开发中,接收应该开子线程。
微信号:yjkhtddx
版权声明:本文为yjkhtddx原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。