我正在尝试使用ssl套接字将文件(此处为视频)发送到我的服务器,我可以发送11次,但是当我再试一次时,我有一个OutOfMemoryError,我想知道如何解决这个问题。
客户端(Android):
InputStream inputStream = null;
try {
inputStream = getAssets().open("test.mp4");
} catch (IOException e) {
e.printStackTrace();
}
byte[] bytes2 = null;
try {
bytes2 = getBytes(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
if (socketConnect()) {
try {
Log.d("MainActivity", "Before OutputStream");
OutputStream os = sock.getOutputStream();
Log.d("MainActivity", "Before FileInputStream");
Log.d("MainActivity", "Before while " + bytes2.length);
os.write(bytes2);
Log.d("MainActivity", "After while");
os.flush();
os.close();
sock.close();
Log.d("MainActivity", "End");
} catch (IOException e) {
e.printStackTrace();
}
}
else {
Log.e("MainActivity", "Erreur");
}
服务器端(Python):
import socket
import sys
import ssl
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("",9999))
sock.listen(10)
i=1
while True:
(clientsocket, (ip, port)) = sock.accept()
connstream = ssl.wrap_socket(clientsocket,
server_side = True,
certfile = "server.crt",
keyfile = "server.key")
f = open('test_'+str(i)+".jpg",'wb') #open in binary
i=i+1
print(i)
l = 1
l = connstream.read(1024)
while (l):
print("toto")
f.write(l)
l = connstream.read(1024)
f.close()
connstream.close()
sock.close()
记录:
05-28 09:56:31.019 11519-11519/com.youstiti.simon.testenvoiwithbuffer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.youstiti.simon.testenvoiwithbuffer, PID: 11519
java.lang.OutOfMemoryError: Failed to allocate a 33552396 byte allocation with 28973408 free bytes and 27MB until OOM
at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)
at com.youstiti.simon.testenvoiwithbuffer.MainActivity.getBytes(MainActivity.java:153)
at com.youstiti.simon.testenvoiwithbuffer.MainActivity.onCreate(MainActivity.java:73)
at android.app.Activity.performCreate(Activity.java:6272)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
at android.app.ActivityThread.access$900(ActivityThread.java:157)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
我认为缓冲区可以解决问题,但我不知道该怎么做。
感谢您的回答
答案 0 :(得分:0)
你必须按块读取和发送你的文件块以避免OOM错误,因为android堆是有限的,如下所示
if (socketConnect()) {
try {
final int bufferSize = 8*1024;
FileInputStream fis = new FileInputStream(/*...your file*/);
byte[] buffer = new byte[bufferSize];
int read;
OutputStream os = sock.getOutputStream();
while( ( read = fis.read( buffer ) ) > 0 ){
os.write(buffer, 0, read);
}
os.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
else {
Log.e("MainActivity", "Erreur");
}
通过添加android:largeHeap="true"
来避免请求大堆,谷歌说:
永远不要因为你的内存不足而请求大堆 你需要快速修复
请查看the doc了解更多