【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

网页播放视频如下:

帅帅帅

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

相关推荐
千天夜29 分钟前
使用UDP协议传输视频流!(分片、缓存)
python·网络协议·udp·视频流
EricWang135830 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
我是谁??32 分钟前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
希言JY1 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
午言若1 小时前
C语言比较两个字符串是否相同
c语言
follycat1 小时前
[极客大挑战 2019]HTTP 1
网络·网络协议·http·网络安全
earthzhang20212 小时前
《深入浅出HTTPS》读书笔记(5):随机数
网络协议·http·https
xiaoxiongip6662 小时前
HTTP 和 HTTPS
网络·爬虫·网络协议·tcp/ip·http·https·ip
JaneJiazhao2 小时前
HTTPSOK:SSL/TLS证书自动续期工具
服务器·网络协议·ssl
JaneJiazhao2 小时前
HTTPSOK:智能SSL证书管理的新选择
网络·网络协议·ssl