各位大神,我在做一个基于安卓运用socket实现视频通信的软件,拿到了一段关于视频线程实现的源码,看完后有以下几个问题求大神解答,1)为什么图片大小要小于14000?
2)大神是否可以简述一下这个实现过程,指点下运用了什么知识什么原理,方便我入门学习
以下为代码:
class ImageThread implements Runnable{
@Override
public void run(){
int image_size;
int image_one_size=1024;
byte image_size_array[]=new byte[4]; //该数组用来接收图片数据大小,尺寸数据为int,所以需要4个字节
byte image_data_array[]; //未知大小,所以先不进行初始化
byte final_image_data_buf[]; //最终图片数据存储区
int numbytes=0; //从socket读入的字节数
int donesize=0; //已经写入数组的字节数
int restsize=0; //未接收完的剩余数据
byte end[]={'e','n','d','\0'}; //每副图片的结束符
//int cnt=0;
try
{
while(!exit_var){
donesize=0;
restsize=0;
//cnt++;
//第一步----图片接收线程正常打开,向server发送ok信息
image_out.println("ok!");
Log.d(DEBUG_TAG, "图片传送请求已发出");
if(image_socket.isConnected()){
if(!image_socket.isInputShutdown()){
//第二步----获得图片大小
image_in.read(image_size_array, 0, 4); //从socket中读数据存入数组中 每次读4个
//Log.d(DEBUG_TAG, "image size array未越界");
// 通过拿到的4个数,就能知道图片的大小有多少
image_size=(image_size_array[0] & 0xff) | ((image_size_array[1] << 8) & 0xff00) // | 表示安位或
| ((image_size_array[2] << 24) >>> 8) | (image_size_array[3] << 24); //把图片尺寸转成int型数据
//第三步,接收图片数据
// OutputStream 是一种管道 ByteArrayOutputStream也是一种管道,但是是一组一组数据的传输
ByteArrayOutputStream imagestream = new ByteArrayOutputStream();
if(image_size>14000){
break;
}
else{
image_data_array=new byte[image_size]; //由于已经获得图片大小,所以此处进行初始化
//Log.d(DEBUG_TAG, "image data array未越界");
//按每组1024个数据读取 加入image_size 1025 1025/1024 读取2次
for(int i=0;i<(image_size/image_one_size);i++)
{
// byte数组 名字叫 image_data_array、
// numbytes 用来判断有多少数据被传过来了
numbytes=image_in.read(image_data_array, donesize, 1024);
if(numbytes==0) break;
donesize=donesize+numbytes;
// 检测是否丢包 如果丢包就重写再传输
if((image_one_size-numbytes)!=0){//读onesize数据出错
restsize=image_one_size-numbytes;
numbytes=image_in.read(image_data_array,donesize, restsize);
if(numbytes==0) break;
donesize=donesize+numbytes;
}
}
//非1024格式数据的读取
if((image_size%image_one_size)!=0){
restsize=image_size-donesize;
numbytes=image_in.read(image_data_array, donesize, restsize);
if(numbytes==0) break;
donesize=donesize+numbytes;
}
}
/*if((image_data_array[image_size-4]!=end[0])||(image_data_array[image_size-3]!=end[1])
||(image_data_array[image_size-2]!=end[2])||(image_data_array[image_size-1]!=end[3]))
{
restsize=image_size-donesize;
numbytes=image_in.read(image_data_array, donesize, restsize);
if(numbytes==0) break;
donesize=donesize+numbytes;
}*/
/*
image_data_array[] = byte [image_size]
10
image_data_array 0 1 2......5 6 7 8 9
'e','n','d','\0'
*
*/
// 判断穿过来的数组是否是图片,是图片的标志是数组以 'e','n','d','\0' 结尾
if((image_data_array[image_size-4]==end[0])&&(image_data_array[image_size-3]==end[1])
&&(image_data_array[image_size-2]==end[2])&&(image_data_array[image_size-1]==end[3]))
{
// 将image_data_array 从0 到倒数第五个放到imagestream中
imagestream.write(image_data_array, 0, (image_data_array.length-4 )); //把图片数据写到数据流中进行包装,防止乱码
// 将imagestream的数据放到final_image_data_buf 数组中
final_image_data_buf=imagestream.toByteArray();
//Log.d(DEBUG_TAG, "final image data array未越界");
imagestream.flush();
imagestream.close();
//第四步,显示图片
// 将数组转化成图片 mbitmap
final Bitmap mbitmap=BitmapFactory.decodeByteArray(final_image_data_buf, 0, final_image_data_buf.length);
MonitorVideoActivity.this.runOnUiThread(new Runnable(){ //刷新了整个activity 更新UI
@Override
public void run(){
mimageview.setImageBitmap(mbitmap);
mimageview.refreshDrawableState();
}
});
}
image_data_array=null;
final_image_data_buf=null;
System.gc();
}
// 线程休息500ms 然后唤醒
Thread.sleep(100); //500ms刷新一次图像线程
Thread.yield();
}
}
}
catch (Exception e)
{
Log.e(DEBUG_TAG,e.toString());
}
finally
{
try{
if(exit_var){
Log.d(DEBUG_TAG, "socket未关闭");
image_out.close();
image_in.close();
ctrl_out.close();
ctrl_socket.close(); //退出时先关socket
image_socket.close();
Log.d(DEBUG_TAG, "socket已关闭");
//MonitorVideoActivity.this.finish();
return; //跳出run方法,结束线程
}
}
catch (Exception e)
{
Log.e(DEBUG_TAG,e.toString());
}
}
}
}
public void send_btn_message(){
try{
switch (button_fig){
case 1:
// 通过DataOutputStream 这个管道 将 “1”传送出去
ctrl_out.writeByte(1);
// flush 确保他完全传送 强制传送一次
ctrl_out.flush();
break;
case 2:
ctrl_out.writeByte(2);
ctrl_out.flush();
break;
case 3:
ctrl_out.writeByte(3);
ctrl_out.flush();
break;
case 4:
ctrl_out.writeByte(4);
ctrl_out.flush();
break;
case 5:
ctrl_out.writeByte(5);
ctrl_out.flush();
break;
}
}
catch(Exception e)
{
Log.e(DEBUG_TAG,e.toString());
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.monitor_video, menu);
return true;
}
}
添加回答
举报
0/150
提交
取消