【SZU计算机网络实验】实现流式视频传输

前言

一百年没有更新博客了,都怪开学一堆杂活(x

那就顺手把实验报告转到这边吧owo

本实验为SZU原创实验,实验开发团队的老师和助教们都很有耐心。。大赞,环境没配好去群里问是秒回的

相关资料:

实验文档:计算机网络课程综合实验平台 (snrc.site)

一、实验介绍

该实验主要实现了一个服务端和一个客户端。其中,服务端利用缓冲区逐段向客户端发送多个视频片段,并在客户端逐段接收,并利用已经设计好的播放器,在网页中播放连续的视频。

二、实验过程

0. 环境搭建

实验文件中包含了压缩包exp1-lib.zip,exp-code.zip,cne.zip

将其解压,并把前两个压缩包(exp1-lib.zip和exp-code.zip)解压后的文件置于一个目录下,于cne.zip解压出来的文件夹devcpp6中的devcppPortable.exe 中打开client.c和server.c文件,选择编译环境为Computer-networks

1. 单文件视频传输

阅读代码发现实验文件中已经实现了:

1)服务端的初始化阶段,包括创建套接字,绑定套接字和监听套接字,以及接收客户端下载请求和发送文件大小给客户端,发送文件结束符和关闭文件。

2)客户端的初始化阶段,向服务器请求文件并接受文件的大小,检查文件结束符后将接收到的视频写入文件中

我们需要实现的是:

1)在服务端:

将文件的内容循环读取到缓冲区中,再将缓冲区的内容发送给客户端,注意读到文件末尾可能无法完整填充整个缓冲区,需要做特判

c 复制代码
        // 发送视频片段
        int send_count = 0;
        while (send_count < file_size)
        {
            /***************************************************************************************************/
            /**************************  任务1: 发送指定视频文件(按照固定大小buffer方式) ********************/
            /***************************************************************************************************/
        	char buffer[BUFFER_SIZE] = {0};
        	  	
        	int bytes_read = (send_count + BUFFER_SIZE <= file_size) ? BUFFER_SIZE : file_size - send_count;
			fread(buffer, bytes_read, 1, fp);
        	
        	bytes_sent = send(new_socket, buffer, bytes_read, 0);
        	if (bytes_sent < 0)
        		printf("ERROR in send video\n");
        	
        	send_count += bytes_sent;
        	printf("video send progress: %d / %d\n", send_count, file_size);
         }

2)在客户端:

接收服务端发送的数据并写入文件。文件末尾无法完整填充缓冲区的处理方式同服务端

c 复制代码
	    int recv_count = 0;
	    
	    while (recv_count < file_size)
	    {		
	        /************************************************************************/
	        /***************** 任务3 : 如何使用buffer接收视频文件?*****************/
	        /************************************************************************/
	        
	        bytes_recv = (recv_count + BUFFER_SIZE <= file_size) ? BUFFER_SIZE : file_size - recv_count;
	        bytes_recv = recv(sock, video_segement + recv_count, bytes_recv, 0);
	        
		recv_count += bytes_recv;
		printf("%s recv progress: %d / %d\n", req, recv_count, file_size);
	    }    

2. 实现流式视频传输

实现流式视频传输要求我们在客户端请求同一个视频的多个视频段,那就利用sprintf 将指定视频名(包括视频名称-视频分辨率-视频码率 )与视频段序号拼接在一起,在客户端循环请求并接收,在服务端循环发送。最后再在客户端调用player.h中设计好的函数,在网页中播放视频

在客户端:

调用StartStreamingServer() 初始化播放器等资源,在循环中利用sprintf构造请求的文件名

c 复制代码
	StartStreamingServer();
	
	for (int id = 0;id < 60; ++id){
	
	    // 发送下载请求
	    int bytes_sent = 0;
	    unsigned char s_stop_byte = 0xFF;
	
	    // 视频文件名
	    char req[REQUEST_SIZE] = "";
	    /******************************************************************/
	    /***************** 任务2:如何按顺序选择视频文件?*****************/
	    /******************************************************************/
		sprintf(req, "ocean-1080p-8000k-%d.ts", id);

	    bytes_sent = send(sock, req, REQUEST_SIZE, 0);
	    if (bytes_sent < 0)
	        printf("ERROR in send\n");
	    bytes_sent = send(sock, &s_stop_byte, sizeof(s_stop_byte), 0);
	    if (bytes_sent < 0)
	        printf("ERROR in send\n");
	    printf("send req: %s\n", req);

接收完成时调用ReceiveSegment()将完整的视频段交付给播放器,等待播放

在结束阶段调用WaitEnd()等待视频播放完毕后关闭播放器

c 复制代码
	    /***数据接收完成阶段***/
		ReceiveSegment(video_segement, req, file_size);
		
	    // 释放内存
	    free(video_segement);    
		video_segement = NULL;
	}	
    /*************************************************************************************/
    /*********任务2(扩展):如何在视频流传输完成后,通知server结束视频传输?*************/
    /*************************************************************************************/
	
	/***结束阶段***/
	closesocket(sock);
	WSACleanup();
	
	WaitEnd();
 }

三、实验结果

先编译运行server.c,服务端启动监听,如下

shell 复制代码
Create Server Socket Success.
Server Bind Port Success.
Server Listening.....

后编译运行client.c,开始依次传输视频文件

shell 复制代码
ocean-1080p-8000k-59.ts recv progress: 178176 / 181608
ocean-1080p-8000k-59.ts recv progress: 179200 / 181608
ocean-1080p-8000k-59.ts recv progress: 180224 / 181608
ocean-1080p-8000k-59.ts recv progress: 181248 / *181608*
ocean-1080p-8000k-59.ts recv progress: 181608 / 181608
file_path .\download\ocean-1080p-8000k-59.ts

网页播放视频如下:

帅帅帅

(其实还有思考题,找时间再研究下

相关推荐
XH华4 小时前
初识C语言之二维数组(下)
c语言·算法
njnu@liyong6 小时前
图解HTTP-HTTP报文
网络协议·计算机网络·http
Uu_05kkq8 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法
kaixin_learn_qt_ing8 小时前
了解RPC
网络·网络协议·rpc
爱吃水果蝙蝠汤10 小时前
DATACOM-IP单播路由(BGP)-复习-实验
网络·网络协议·tcp/ip
嵌入式科普10 小时前
十一、从0开始卷出一个新项目之瑞萨RA6M5串口DTC接收不定长
c语言·stm32·cubeide·e2studio·ra6m5·dma接收不定长
A懿轩A10 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
1 9 J11 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
仍然探索未知中12 小时前
C语言经典100例
c语言
爱吃西瓜的小菜鸡13 小时前
【C语言】矩阵乘法
c语言·学习·算法