前言
這個解決方案是我和隊友在《物聯(lián)網(wǎng)》比賽的集訓中得到的。在socket中Android客戶端接收圖片是相當?shù)募郑ǚ凑耶敃r就是這樣覺得)倔喂,接收文字還算簡單铝条。在剛開始接觸socket接收圖片的時候,出現(xiàn)一大堆意想不到的結(jié)果席噩,要么圖片顯示不出來班缰,要么圖片顯示不完整都有可能,下面我給出自己的解決方案悼枢,如果您有幸碰到了這個問題而且正在不知道怎么解決而發(fā)愁的時候埠忘,希望這篇文章能給您一些幫助。
開車
相信你們剛開始也會像我一樣犯了這樣一個錯誤用了下面這一段代碼處理流的接收
while((len = inputStream.read(bs))!=-1)
這段代碼并沒有錯馒索,只是我們還不太了解socket通信的原理莹妒。
當你在socket使用這段代碼,你將永遠都接收不到數(shù)據(jù)绰上,因為socket一旦通信是一直連接旨怠,所以永遠得不到返回-1,除非對方斷開連接蜈块。還有在socket通信中不能隨便關(guān)閉流鉴腻,否則將影響雙方的通信,要在適當?shù)臅r候關(guān)閉流才是最佳的做法疯趟。
核心代碼
由于我寫的是簡單的接收和發(fā)送拘哨,沒有其他的東西,所以我直接貼核心代碼就行信峻,當然我也會把源碼鏈接放在下面給大家共享。
接收圖片
Socket socket = new Socket("192.168.162.59", 9999);
InputStream inputStream = socket.getInputStream();
//begin 圖片接收
//第1步:接收服務端發(fā)過來的圖片大小
byte[] picLenBuff = new byte[200];
int picLen = inputStream.read(picLenBuff);
//將String 轉(zhuǎn)換成 int
String picLenString = new String(picLenBuff, 0, picLen);
int getPicLen = Integer.valueOf(picLenString);
//第2步:回饋瓮床。向服務端反饋客戶端已經(jīng)接收到圖片的大小了盹舞,可以開始發(fā)圖片了
OutputStream outputStream = socket.getOutputStream();
String string = "1";
outputStream.write(string.getBytes());
outputStream.flush();
//第3步:開始接收圖片
int offset = 0;//定義偏移量
byte[] bitmapBuff = new byte[getPicLen];//初始化圖片緩存
/**********************最主要部分***********************/
while(offset < getPicLen)
{
int len = inputStream.read(bitmapBuff, offset, getPicLen-offset);
offset+=len;
}
/**********************最主要部分***********************/
//開始圖片解碼
Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapBuff, 0, offset);
//用handler通知UI線程顯示圖片
Message message = handler.obtainMessage(1, bitmap);
handler.sendMessage(message);
//end
發(fā)送圖片
Socket socket = new Socket("192.168.162.59", 9999);
OutputStream outputStream = socket.getOutputStream();
//初始化2M以內(nèi)的圖片緩存
byte[] PicBuff = new byte[1024*1024*2];
FileInputStream fileInputStream = new FileInputStream(Environment.getExternalStorageDirectory()+"/20.png");
//得到圖片大小
int lenPic = fileInputStream.read(PicBuff);
String lenString = String.valueOf(lenPic);
//向服務端發(fā)送圖片大小
outputStream.write(lenString.getBytes());
outputStream.flush();
//定義回饋
byte[] getRec = new byte[1];
InputStream inputStream = socket.getInputStream();
inputStream.read(getRec);
String string = new String(getRec);
//如果得到回饋是1产镐,說明服務端已經(jīng)接收完圖片大小,可以開始發(fā)送圖片了
if(string.equals("1"))
{
outputStream.write(PicBuff, 0, lenPic);
outputStream.flush();
}
以上通信格式都需要事先和PC端說好踢步,否則通信失敗癣亚。
這里只要講解下接收圖片這段代碼要注意的地方
/**********************最主要部分***********************/
while(offset < getPicLen)
{
int len = inputStream.read(bitmapBuff, offset, getPicLen-offset);
offset+=len;
}
/**********************最主要部分***********************/
- 如果PC服務端發(fā)送的圖片比較大,Android客戶端不可能一次性讀完全部輸入流获印,所以要在while(offset < getPicLen)中循環(huán)讀取述雾。
- read函數(shù)中的第三個參數(shù)要減去偏移量,否則會出現(xiàn)圖片顯示不完整或顯示不出來等問題兼丰。
源碼點擊下載