各位大神,我在做一个基于安卓运用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; } }