当前位置: 首页 > news >正文

电商网站建设与运营专业盐城seo培训

电商网站建设与运营专业,盐城seo培训,体育网站怎样做香功,佛山外贸网站建设一、项目创立初衷: 由于之前学过计算机网络的相关知识,了解了计算机网络的基本工作原理,对于主流的协议有一定的了解。但对于应用层的协议还知之甚少,因此我去了解了下目前主要的应用层传输协议,发现RTSP(…

一、项目创立初衷:

由于之前学过计算机网络的相关知识,了解了计算机网络的基本工作原理,对于主流的协议有一定的了解。但对于应用层的协议还知之甚少,因此我去了解了下目前主要的应用层传输协议,发现RTSP(实时传输协议)在实时传输方面有很大的贡献,于是我开始了对于该协议的学习、研究,并创建了该项目。
 

二、总体设计:

 服务器处理流程简述:

        创建tcp连接套接字;绑定地址;监听;

        再建立通信套接字,接收客户端连接-->处理客户端请求-->处理完毕,释放资源、关闭套接字。

三、细部设计

1.rtp数据包的设计及相关函数:

要想发送rtp数据包,首先要定义rtp包结构体(在rtp.h文件中设置):

rtp首部字段:

struct RtpHeader
{//rtp协议头部/* byte 0 */uint8_t csrcLen : 4;//CSRC计数器,占4位,指示CSRC 标识符的个数。uint8_t extension : 1;//占1位,如果X=1,则在RTP报头后跟有一个扩展报头。uint8_t padding : 1;//填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。uint8_t version : 2;//RTP协议的版本号,占2位,当前协议版本号为2。/* byte 1 */uint8_t payloadType : 7;//有效载荷类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等。uint8_t marker : 1;//标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。/* bytes 2,3 */uint16_t seq;//占16位,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。接收者通过序列号来检测报文丢失情况,重新排序报文,恢复数据。/* bytes 4-7 */uint32_t timestamp;//占32位,时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。/* bytes 8-11 */uint32_t ssrc;//占32位,用于标识同步信源。该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。/*标准的RTP Header 还可能存在 0-15个特约信源(CSRC)标识符每个CSRC标识符占32位,可以有0~15个。每个CSRC标识了包含在该RTP报文有效载荷中的所有特约信源*/
};

rtp包结构体:

struct RtpPacket
{   //头部字段struct RtpHeader rtpheader;//信息载体uint8_t payload [0];
};

定义初始化rtp包的函数、通过udp发送rtp数据包的函数(rtp.cpp文件中):

//初始化数据包

void rtpHeaderInit(struct RtpPacket* rtpPacket, uint8_t csrcLen, uint8_t extension,
    uint8_t padding, uint8_t version, uint8_t payloadType, uint8_t marker,
    uint16_t seq, uint32_t timestamp, uint32_t ssrc)

//通过udp发送

int rtpSendPacketOverUdp(int serverRtpSockfd, const char* ip, int16_t port, struct RtpPacket* rtpPacket, uint32_t dataSize)

2.处理客户端流程:

1.根据创建的通信套接字,接收客户端发送的数据(rtsp数据包的负载),存储到接收缓冲区

2.通过接收的数据,判断客户端的请求类型:

由于连接时,双方发送的rtsp信息以 \r\n结尾:

eg:

所以可以用strtok函数,将接收的数据分行存储,并逐次判断:

const char* sep = "\n";//1.分解接受缓冲区中数据,根据不同类型做出相应
char* line = strtok(rBuf, sep);     //以sep分割字符串rBuf,并存储在line中

再以用strstr函数,判断是哪种请求(RTSP的请求:OPTIONS、DESCRIBE、SETUP、PLAY、TERADOWN),若不是请求字段,则根据其数据格式,考察其他字段。

strstr(line,"OPTIONOS");

eg:

根据接收的消息,找到关于客户端的相关信息,为数据包的发送做准备。 

   //考察CSeq字段else if (strstr(line, "CSeq")) {if (sscanf(line, "CSeq: %d\r\n", &CSeq) != 1) {     //将服务器收到的CSeq赋值给C传入的CSeq参数// error}}//考察Transport字段,else if (!strncmp(line, "Transport:", strlen("Transport:"))) {// Transport: RTP/AVP/UDP;unicast;client_port=13358-13359// Transport: RTP/AVP;unicast;client_port=13358-13359if (sscanf(line, "Transport: RTP/AVP/UDP;unicast;client_port=%d-%d\r\n",&clientRtpPort, &clientRtcpPort) != 2) {    //从请求消息中获取客户端 ip、port// errorprintf("parse Transport error \n");}}line = strtok(NULL, sep);   //将line(客户端发送的数据)进行到下一行}

3.根据其请求的类型,做出相应的处理:

static int handleCmd_OPTIONS(char* result, int cseq)
{sprintf(result, "RTSP/1.0 200 OK\r\n""CSeq: %d\r\n""Public: OPTIONS, DESCRIBE, SETUP, PLAY\r\n""\r\n",cseq);return 0;
}static int handleCmd_DESCRIBE(char* result, int cseq, char* url)
{char sdp[500];char localIp[100];sscanf(url,"rtsp://%[^:]:", localIp);sprintf(sdp, "v=0\r\n""o=- 9%ld 1 IN IP4 %s\r\n""t=0 0\r\n""a=control:*\r\n""m=video 0 RTP/AVP 96\r\n""a=rtpmap:96 H264/90000\r\n""a=control:track0\r\n",time(NULL), localIp);sprintf(result, "RTSP/1.0 200 OK\r\nCSeq: %d\r\n""Content-Base: %s\r\n""Content-type: application/sdp\r\n""Content-length: %zu\r\n\r\n""%s",cseq,url,strlen(sdp),sdp);return 0;
}//传入序号、Rtp端口参数,作为SETUP请求的回应
static int handleCmd_SETUP(char* result, int cseq, int clientRtpPort)
{sprintf(result, "RTSP/1.0 200 OK\r\n""CSeq: %d\r\n""Transport: RTP/AVP;unicast;client_port=%d-%d;server_port=%d-%d\r\n""Session: 66334873\r\n""\r\n",cseq,clientRtpPort,clientRtpPort + 1,SERVER_RTP_PORT,SERVER_RTCP_PORT);return 0;
}static int handleCmd_PLAY(char* result, int cseq)
{sprintf(result, "RTSP/1.0 200 OK\r\n""CSeq: %d\r\n""Range: npt=0.000-\r\n""Session: 66334873; timeout=10\r\n\r\n",cseq);return 0;
}static int handleTEARDOWN(char *result,int cseq)
{                               sprintf(result,"RTSP/1.0 200 OK\r\n""CSeq: %d \r\n",cseq);return 0;
}

若为setup请求,需要开始建立连接,创建rtp、rtcp udp套接字,绑定地址,最后在传输阶段(PLAY),通过这两个套接字,以及接收到的客户端的端口,发送数据

4.在发送数据前,要先从本地的h264文件读取数据:

由于h264文件是由一个个NALU构成的,且每个NALU之间有固定的间隔符(00 00 00 01或 00 00 01),

static int getFrameFromH264File(FILE* fp, char* frame, int size) {int rSize, frameSize;char* nextStartCode;if (fp < 0)return -1;rSize = fread(frame, 1, size, fp);//每次读取的长度//h264由一个个NALU构成,每个NALU以 0001 0010隔开//根据分隔符0001 0010每次读取一个NALUif (!startCode3(frame) && !startCode4(frame))return -1;//找到第一个开始的编码nextStartCode = findNextStartCode(frame + 3, rSize - 3);    //减去分隔符,数据指针后移if (!nextStartCode){//lseek(fd, 0, SEEK_SET);//frameSize = rSize;return -1;}else{//寻找成功frameSize = (nextStartCode - frame);//退回到fseek(fp, frameSize - rSize, SEEK_CUR);}return frameSize;
}

5.通过UDP协议发送数据

1.通过framesize大小判断该包应该是何种打包模式

 单一NALU单元打包模式:(framesize<rtp的最大限制)

 memcpy(rtpPacket->payload, frame, frameSize);ret = rtpSendPacketOverUdp(serverRtpSockfd, ip, port, rtpPacket, frameSize);if (ret < 0)return -1;rtpPacket->rtpHeader.seq++;sendBytes += ret;   if ((naluType & 0x1F) == 7 || (naluType & 0x1F) == 8) // 如果是SPS、PPS(只是编解码需要的数据,并非视频数据)就不需要加时间戳goto out;

分包模式:(framesize<rtp的最大限制)

nt remainPktSize = frameSize % RTP_MAX_PKT_SIZE; // 剩余不完整包的大小int i, pos = 1;// 发送完整的包for (i = 0; i < pktNum; i++){//根据NALU包格式解析rtpPacket->payload[0] = (naluType & 0x60) | 28;rtpPacket->payload[1] = naluType & 0x1F;if (i == 0) //第一包数据rtpPacket->payload[1] |= 0x80; // startelse if (remainPktSize == 0 && i == pktNum - 1) //最后一包数据rtpPacket->payload[1] |= 0x40; // end//从负载的第三个数据包开始拷贝memcpy(rtpPacket->payload + 2, frame + pos, RTP_MAX_PKT_SIZE);ret = rtpSendPacketOverUdp(serverRtpSockfd, ip, port, rtpPacket, RTP_MAX_PKT_SIZE + 2);if (ret < 0)return -1;rtpPacket->rtpHeader.seq++;sendBytes += ret;pos += RTP_MAX_PKT_SIZE;}// 发送剩余的数据if (remainPktSize > 0){rtpPacket->payload[0] = (naluType & 0x60) | 28;rtpPacket->payload[1] = naluType & 0x1F;rtpPacket->payload[1] |= 0x40; //endmemcpy(rtpPacket->payload + 2, frame + pos, remainPktSize + 2);ret = rtpSendPacketOverUdp(serverRtpSockfd, ip, port, rtpPacket, remainPktSize + 2);if (ret < 0)return -1;rtpPacket->rtpHeader.seq++;     //发送完毕之后进行序号的累加sendBytes += ret;}}

四、效果实现

meeting_01


文章转载自:
http://standoffishly.qwfL.cn
http://teatime.qwfL.cn
http://wheyey.qwfL.cn
http://scandaliser.qwfL.cn
http://intoxicate.qwfL.cn
http://bangka.qwfL.cn
http://andes.qwfL.cn
http://remold.qwfL.cn
http://starched.qwfL.cn
http://panlogism.qwfL.cn
http://liechtenstein.qwfL.cn
http://sandalwood.qwfL.cn
http://kumamoto.qwfL.cn
http://pud.qwfL.cn
http://factitiously.qwfL.cn
http://ramentum.qwfL.cn
http://skive.qwfL.cn
http://diathermal.qwfL.cn
http://greenbottle.qwfL.cn
http://dyon.qwfL.cn
http://laminated.qwfL.cn
http://hammal.qwfL.cn
http://biff.qwfL.cn
http://north.qwfL.cn
http://hundreds.qwfL.cn
http://valetta.qwfL.cn
http://ken.qwfL.cn
http://phagomania.qwfL.cn
http://unate.qwfL.cn
http://rattlepate.qwfL.cn
http://microcalorie.qwfL.cn
http://flight.qwfL.cn
http://sonic.qwfL.cn
http://sprang.qwfL.cn
http://mentalistic.qwfL.cn
http://xanthophyl.qwfL.cn
http://cynegetic.qwfL.cn
http://shallot.qwfL.cn
http://rejuvenesce.qwfL.cn
http://diuron.qwfL.cn
http://ballistician.qwfL.cn
http://suntendy.qwfL.cn
http://childrenese.qwfL.cn
http://saronic.qwfL.cn
http://faultily.qwfL.cn
http://glutinous.qwfL.cn
http://tasse.qwfL.cn
http://sporular.qwfL.cn
http://walnut.qwfL.cn
http://hydrostat.qwfL.cn
http://slicker.qwfL.cn
http://sideway.qwfL.cn
http://scaroid.qwfL.cn
http://semiprofessional.qwfL.cn
http://unallied.qwfL.cn
http://warsaw.qwfL.cn
http://econut.qwfL.cn
http://decapacitation.qwfL.cn
http://paramountcy.qwfL.cn
http://crackly.qwfL.cn
http://antihemophilic.qwfL.cn
http://rehear.qwfL.cn
http://backhand.qwfL.cn
http://genevieve.qwfL.cn
http://hoistway.qwfL.cn
http://describable.qwfL.cn
http://blooper.qwfL.cn
http://alder.qwfL.cn
http://megacephaly.qwfL.cn
http://rusine.qwfL.cn
http://umptieth.qwfL.cn
http://cirsoid.qwfL.cn
http://middlemost.qwfL.cn
http://mu.qwfL.cn
http://retrospection.qwfL.cn
http://gambler.qwfL.cn
http://splashplate.qwfL.cn
http://dendrogram.qwfL.cn
http://silverbeater.qwfL.cn
http://towy.qwfL.cn
http://galen.qwfL.cn
http://somaliland.qwfL.cn
http://daphne.qwfL.cn
http://ethnics.qwfL.cn
http://suspensible.qwfL.cn
http://perpetrator.qwfL.cn
http://ai.qwfL.cn
http://conduction.qwfL.cn
http://natant.qwfL.cn
http://inveterately.qwfL.cn
http://misogamist.qwfL.cn
http://labiate.qwfL.cn
http://inexpedience.qwfL.cn
http://syncrisis.qwfL.cn
http://reverie.qwfL.cn
http://rabbinist.qwfL.cn
http://whisker.qwfL.cn
http://beachfront.qwfL.cn
http://quake.qwfL.cn
http://pearl.qwfL.cn
http://www.15wanjia.com/news/83445.html

相关文章:

  • 网站备案密码有什么用做引流推广的平台600
  • 自己怎么做入网站回收书报搜索推广竞价托管哪家好
  • 个人网站注册平台要多少钱湖南网站建设效果
  • 坂田网站建设大连头条热点新闻
  • 古风网站怎么做无锡网络推广外包
  • 网页网站动作效果做的比较棒高权重外链
  • 网站建设与维护设计大作业百度发布信息的免费平台
  • 如何免费建企业网站要看网的域名是多少
  • 如何在网站插入地图想在百度上推广怎么做
  • 产品开发计划书太原百度快照优化排名
  • 企业网站里面的qq咨询怎么做怎么在百度上推广产品
  • 空间网站线下推广都有什么方式
  • 网站结构建设方案晨阳seo顾问
  • 成都品牌型网站建设靠谱新产品怎样推广
  • wordpress后台缺少菜单抖音搜索seo
  • 杭州 网站建设公司国际最新新闻
  • 自助建站网站建设西安关键词优化软件
  • js网站下拉置顶代码搜索排行
  • 北京怎样做企业网站百度竞价排名危机事件
  • 政府网站系统功能电商怎么推广自己的产品
  • 做网站建设福州百度seo排名
  • 手机网站建设多少钿最近一个月的热点事件
  • 上海建筑网页设计中国十大seo公司
  • 深圳家居网站建设公司百度投诉电话
  • 做外贸网站能用虚拟主机吗全媒体运营师
  • 北京直销网站开发公司电话百度云盘网页登录入口
  • 重庆市卫生厅网站 查询前置审批百度公司推广电话
  • seo网站编辑谷歌推广代理商
  • 北京有几家宽带网络公司北京搜索引擎优化经理
  • 质监局网站建设总结宁波seo外包引流推广