我正在android studio中编写一个与python服务器通信的程序。我试图发送一条长消息(以base64编码的mp3文件-大约10k字节)。问题是,当我检查服务器中收到的内容时,得到的字节数少于10k。
有人知道如何解决吗?
谢谢。
记录消息并将其放入base64:
// Record audio from user in mp3 format
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setOutputFile(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/messageRecord.mp3");
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.prepare();
recorder.start();
TimeUnit.SECONDS.sleep(5);
recorder.stop();
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/messageRecord.mp3");
int size = (int) file.length();
byte[] bytes = new byte[size];
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(bytes, 0, bytes.length);
buf.close();
String content = Base64.encodeToString(bytes, Base64.DEFAULT);
// Prepare audio message request
JSONObject sendRecordReq = new JSONObject();
sendRecordReq.put("code", Codes.SPEECH_TO_TEXT_CODE);
sendRecordReq.put("src_phone", ChatScreen.this.srcPhone);
sendRecordReq.put("dst_phone", ChatScreen.this.dstPhone);
sendRecordReq.put("content", content);
// Send message request
ChatScreen.this.client.send(sendRecordReq);
我如何发送:
//In class client
public void send(JSONObject request) {
this.outgoingMessages.addConversationFlow(request); //Send request
}
//In class OutgoingMessages
public void run() {
try {
while (true) {
while(!this.conversationFlow.isEmpty()) {
JSONObject msgToSend = this.conversationFlow.remove();
String strRequest = msgToSend.toString();
this.out.write(Integer.toString(strRequest.length()).getBytes()); //Sends message size
this.out.write(strRequest.getBytes()); //Sends message
}
}
}
catch (Exception e) {
System.out.println(e);
}
}
服务器:
while True:
# Receiving data size from client
message_size = int(client_socket.recv(MAX_SIZE_LEN))
# Receiving data from the client
client_message = client_socket.recv(message_size)
print client_message
# Add message to messages queue with client's socket
MESSAGES_QUEUE.append((client_socket, client_message))
编辑: “ message_size”值是正确的(14806-在下一行中应接收的消息大小),但仍不能全部接收。
EDIT2: 我想通了,把解决方案贴在答案中
答案 0 :(得分:0)
您的Java代码正在以无法正常工作的协议发送数据。
如果输入的JSON对象是字符串'a',则将其发送:
3"a"
如4个字节:51、34、97、34。
“这是数据多长时间”部分结束时,python端不知道。
我假设您打算发送的内容类似于:
00, 00, 00, 03, 34, 97, 34.
换句话说:4个字节,包含一个网络字节序,先发送带有长度的整数值,然后再发送那么多字节。
另外,请勿致电.getBytes()
;将字符串转换为字节时,应始终明确指定编码。根据定义,JSON或多或少都是UTF-8,因此,请改为调用.getBytes("UTF-8")
。
注意:要替换您的“发送长度”代码,请参见Convert integer into byte array (Java)
答案 1 :(得分:0)
所以问题不在于文件的长度或其他任何东西。问题在于,python中的recv函数将获取一些字节,但是由于某些原因,代码仍在继续,因此未获得完整的消息。
解决方案是添加一个函数,直到收到指定的整个长度,该函数才继续。我在下一篇文章中找到了解决方案: Python Socket Receive Large Amount of Data
我还将添加代码:
用recvall(socket,size)替换recv函数。这不是我的代码,由亚当·罗森菲尔德(Adam Rosenfield)发布,由海德·范·德·海德(Hedde van der Heide)编辑。
def recvall(sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = b''
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return data