我需要使用來自我的android應用程序的套接字將數據包發送到服務器。我只知道一個包的佈局:android java socket寫入和接收byte []數據
Packet ID 4 bytes | Packet length 4 bytes(minus len + ID) | payload (protobuf message)
關於TLSv1.2連接和自簽名證書的整個工作很好。例如,我需要發送認證數據包 - 如果數據包發送成功,LoginRequest和服務器將響應LoginResponse。我正在嘗試做的是連接到AsyncTask類中的服務器,寫入數據並接收響應,但顯然我做錯了,因爲我沒有迴應。對於寫作和閱讀信息的代碼:
LoginRequest protobuf的消息:
Protos.LoginRequest loginRequest = Protos.LoginRequest.newBuilder()
.setUsername(mailAddress)
.setPassword(pass).build();
和代碼(內部doInBackground()方法):
//TLSSocketFactory is custom SSLSocketFactory class for forcing TLSv1.2 on devices > 16 & < 20
socket = tlsSocketFactory.createSocket("airwave1.exurion.com", 2559);
byte[] payload = loginRequest.toByteArray();
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
InputStream inStream = socket.getInputStream();
out.writeInt(10); //ID of the packet
out.writeInt(payload.length);
out.write(payload);
out.flush();
byte[] data = new byte[100];
int count = inStream.read(data);
out.close();
inStream.close();
socket.close();
正如我說我沒有迴應,有時在閱讀郵件時我也會遇到SSLException:
javax.net.ssl.SSLException: Read error: ssl=0xb3a28580: I/O error during system call, Connection timed out
有沒有人有ide一個如何解決這個問題?
//修訂 我想通了,字節順序需要在LITTLE_ENDIAN,所以我試圖用的ByteBuffer:
//based on previous packet layout (4 bytes for ID, 4 bytes for payload length, and payload) - is it ByteBuffer.allocate() fine?
ByteBuffer buffer = ByteBuffer.allocate(8 + payload.length);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putInt(LoginPacketType.LOGIN_REQUEST.getId());
buffer.putInt(payload.length);
buffer.put(payload);
buffer.rewind();
byte[] result = new byte[buffer.capacity()]; // Could also use result = buffer.array();
buffer.get(result);
out.write(result);
但現在我得到OOM異常:
Failed to allocate a 184549388 byte allocation with 16777216 free bytes and 155MB until OOM
詳細信息關於此問題: 寫入DataOutputStream後,我將:
buffer.clear()
out.flush();
//code for reading from InputStream
而現在,在我的日誌出現此消息幾次: 啓動阻斷GC的Alloc
,比拋出OOM異常。
感謝您的提示,但仍然不工作,它堅持閱讀。發送數據包可能是問題所在,但我無法弄清楚。 – slena17
如果此代碼卡在讀取中,另一端不發送此協議。 – EJP