【rtsp client取海康IPC H264视频流】---socket创建

        近一年来,听到最多的就是某某功能网上有开源的,为什么不用开源的非得要自己写,诚然,开源的优点不言而喻,稳定、快速集成等等,可是既然你做了这个模块为何不认真的搞清楚其内部机制呢?写通过rtsp协议取海康IPC视频流的时候,个人花了一个月从前期的理解,查资料以及GitHub上找开源的优质代码,最终站在巨人的肩上,才匆匆忙忙的完成了模块的开发,虽然代码质量不及开源,然而机制了于胸,个人觉得已经满足了。

                                                                                                        -------2022.07.18个人感想

        RTSP(Real Time Streaming Protocol),实时流传输协议,是基于TCP/IP协议实现的一个应用协议,RTSP包括RTP和RTCP,其中RTP用于音视频传输协议,RTCP用于控制传输,数据的传输可以基于TCP也可以基于UDP完成。

        上述的基本介绍包含了多重信息,通过下面图进一步加深了解。  

 根据上图,我们可以了解到,要实现一个RTSP CLIENT,我们要经历至少四步;

1、通过TCP/IP创建socket连接服务端;

2、实现RTSP协议,通过OPTIONS、DESCRIBE、SETUP、PLAY方法实现与server的交互;

3、通过TCP/UDP解析RTP包,实现对音视频数据解封装,根据协议视频解析为H264orH265等,音频解析为aac等。

4、销毁连接,释放资源

TCP/IP实现socket通过IP端口连接服务器

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include <sys/types.h>
#include<sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include<netinet/in.h>
//https://blog.csdn.net/xiongya8888/article/details/96996236
int socket_select_connect(int handler,unsigned int timeout)
{
    int ret ;
    fd_set write_set;
    struct timeval tv;

    FD_ZERO(&write_set);
    FD_SET(handler,&write_set);

    tv.tv_sec = timeout;
    tv.tv_usec = 0;
    ret = select(handler + 1,NULL, &write_set,NULL,&tv);
    if(ret <= 0){
        close(handler);
        return -1;
    }

    return 0;
}
int socket_connect_by_time(int handler,struct sockaddr *server,size_t len,unsigned int timeout)
{
    int ret = 0;

    if(handler < 0){
        return -1;
    }
    if(NULL == server){
        return -1;
    }

    ret = connect(handler,server,len);
    if(0 != ret && EINPROGRESS == errno){
        ret = socket_select_connect(handler,timeout);
    }

    return ret;

}
/*
    socket connect server 
    1、创建socket,将socket设置为非阻塞模式
    2、调用connect链接,若立即返回0则表示链接成功,不能链接则返回-1,这时候通过错误码是否表示暂时不能完成,如果是继续下一步。
    3、调用select在指定的时间内判断socket是否可写,如果可写表明connect链接成功,返回socket句柄
*/
int socket_connect_server(char *ip_addr,unsigned short port,unsigned int timeout)
{
    struct sockaddr_in server_addr;
    int socket_fd = 0;
    int r = 0;
    int flags;
    if(NULL == ip_addr){
        printf("[%s:%d] ip addr is null\n",__FUNCTION__,__LINE__);
        return -1;
    }

    bzero(&server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(ip_addr);
    server_addr.sin_port = htons(port);

    socket_fd = socket(AF_INET,SOCK_STREAM,0);
    if(socket_fd < 0){
        printf("[%s:%d]create socket fail\n",__FUNCTION__,__LINE__);
        return -1;
    }

    //非阻塞
    flags = fcntl(socket_fd,F_GETFL,0);
    fcntl(socket_fd,F_SETFL,flags|O_NONBLOCK);

    r = socket_connect_by_time(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr),timeout);

    return 0 == r ? socket_fd:-1;

}
#if 0   //test
int main()
{
    int handler = -1;
    handler = socket_connect_server("192.168.1.30",8080,5);
    printf("[%s:%d]handler is[%d]\n",__FUNCTION__,__LINE__,handler);
    if(handler > 0){
        close(handler);
    }
}
#endif

以上代码通过IP和端口实现对server的链接,这也是我们实现rtsp client的第一步,通过TCP/IP链接server,基于这一步,后面实现rtsp 协议中的OPTIONS DESCRIBE SETUP PLAY TRARDOWN等方法的实现。

猜你喜欢

转载自blog.csdn.net/weihan0208/article/details/125841719