這幾天小編在工做中遇到了一個靈異事件,客戶端使用的是安卓原生系統,服務端使用的是java。需求就是客戶端在照相的時候能夠實時上傳照片。後臺接收並保存,而且能夠在平臺上顯示。看似簡單的功能,確有個很大的坑。有2個平臺,192.168.31.87平臺是測試環境,192.168.31.239是演示環境,測試環境,演示環境,還有安卓客戶端代碼都是同樣的,連mq,redis,nginx,數據庫都是同樣的。可是安卓端上傳測試環境一直報java.net.SocketException,在演示環境上是正常的。檢查服務端代碼。我首先用了postman進行測試.php
因爲已經上傳過一張同樣的照片,因此這裏返回failed,可是請求是200.說明是調用正常。而後我在微服務上寫了個測試類,用httpclient調用結果也是正常。html
在安卓客戶端上傳的時候,正常和不正常的log分別是前端
正常:
response-->Response{protocol=http/1.1, code=200, message=OK, url=http://192.168.31.239:8081/api/collDataUpload?para={%22fileName%22:%2220180822_185110_523.jpg%22,%22pno%22:%2220180821%22,%22dkey%22:%2215948c07-c718-4f32-a0af-4b7841fa95a0%22,%22stime%22:%221534935070523%22,%22etime%22:%221534935071000%22}} 不正常: response-->Response{protocol=http/1.1, code=400, message=, url=http://192.168.31.87:8081/api/collDataUpload?para={%22fileName%22:%2220180822_184559_902.jpg%22,%22pno%22:%228230%22,%22dkey%22:%22d351aa68-bace-438f-8d08-89ff598d4e04%22,%22stime%22:%221534934759902%22,%22etime%22:%221534934760000%22}}
安卓客戶端部分代碼java
/** * 同步基於post的圖片上傳 * * @param url * @param file * @return */ public Response uploadPic(String url, File file, String fileName) throws IOException { MultipartBody.Builder builder = new MultipartBody.Builder(); builder.setType(MultipartBody.FORM); Log.i("huang", "files[0].getName()==" + files[0].getName()); //第一個參數要與Servlet中的一致 builder.addFormDataPart("file", fileName, RequestBody.create(MediaType.parse(guessMimeType(fileName)), file)); MultipartBody multipartBody = builder.build(); Request request = new Request.Builder().url(url).post(new ProgressRequestBody(multipartBody, listener)).build(); okHttpClient.newCall(request).enqueue(callback); }
服務端linux
而後客戶端調用服務端連這個接口都沒進來,首先我判斷配置文件是否有對文件大小進行過濾,而後看了filter也沒什麼。百思不得奇解。因而作了不少操做。雖然最後問題仍是沒=解決,可是到get到了不少新技能。
很是重要的一個技能:抓包。
···
大體步驟爲:
1.首先在linux服務器上執行指令
2.調用接口,而後執行指令把linux文件下載到本地
3.使用Wireshark查看日誌
須要使用的linux命令
netstat -tupln | grep 5088
tcpdump -i any -p -s 0 -w /tmp/cap.pcap
sz /tmp/cap.pcap
···nginx
而後到開始菜單換中打開redis
Wireshark這軟件,小夥伴百度下載便可
地址欄中能夠輸入過濾條件:
ip.addr == 192.168.31.182 and http數據庫
選中其中你想看的包,右鍵追溯流--->TCP流或者http流api
這裏大體解釋一下:
Content-Type:是上傳文件格式multipart/form-data是指圖片。
boundary=XXXX,這是前端傳的時候使用的一種形式addBoundary
Content-Length是內容大小
Host:是服務器主機地址
Connection是連接狀態
Accept-Encoding是接收的編碼格式
User-Agent:是用戶上傳的形式,這裏安卓使用的是okhttp/3.6.0
content-Desposition是上下文的描述
content-Type:內容類型
很開心,又get到了一個新技能,可是個人問題仍是沒有解決。目前的解決辦法就是本身在寫個安卓端,單獨用作個按鈕,而後用okhttp上傳文件到平臺。
另外在操做安卓的時候遇到了adb.exe已中止工做,而後開啓不了虛擬機的問題。服務器
出錯畫面:
通常出現這個錯誤的緣由都是因爲adb的默認端都5037,被其餘程序佔用了。擼主我就碰到過被酷我音樂,魯大師和被360mobile的exe程式佔用了,後來這些程式所有被我刪了!
首先咱們應該在電腦中查看5037的端口狀況,輸入 netstat -aon|findstr "5037":
咱們能夠看到PID爲4476的程式使用了關端口,然我咱們打開任務管理器。
咱們能夠看到進程爲「360MobileLoader.exe *32」的進程佔用了5037端口。理論上來講咱們結束這個進程應該就好了。可是問題來了!
竟然不讓我刪除!!!!!!!!PS:我本身的電腦,刪不刪除還須要你的贊成?
選擇打「」開文件位置「」,找到對應的exe程式,我這兒使用的是360強制刪除,PS:普通刪除的方一樣不容許我刪除。
我刪除了以後,電腦從新註銷了一下,adb.exe正常啓動起來了。
Genymotion又開啓了。小姐姐又回來了哈哈。
在附送一個知識:無界鼠標.就是一個鼠標鍵盤控制N臺電腦(能夠是不一樣操做系統)
附上連接