我正在尝试从Android中的客户端读取服务器套接字中的数据。
以下是我正在使用的代码片段:
客户端(在JAVA的Android上)
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
if (client.socket == null || !client.socket.isConnected())
client.createSocket();
// Get Input/Output stream for socket
dataOutputStream = new DataOutputStream(client.socket.getOutputStream());
dataInputStream = new DataInputStream(client.socket.getInputStream());
// Here RS is simple JAVA class that stores information about payload and response length
Log.d("Send", "Sending payload for pair " + RS.getc_s_pair() + " " + RS.getResponse_len());
dataOutputStream.write(UtilsManager.serialize(RS.getPayload()));
// Notify waiting Queue thread to start processing next packet
if (RS.getResponse_len() > 0) {
Log.d("Response", "Waiting for response for pair " + RS.getc_s_pair() + " of " + RS.getResponse_len() + " bytes");
int totalRead = 0;
byte[] buffer = new byte[RS.getResponse_len()];
while (totalRead < RS.getResponse_len()) {
int bytesRead = dataInputStream.read(buffer, totalRead, RS.getResponse_len() - totalRead);
if (bytesRead < 0) {
throw new IOException("Data stream ended prematurely");
}
totalRead += bytesRead;
}
}
服务器(Python)
# Here request_len is the expected request size
while buffer_len < response_set.request_len:
new_data = connection.recv( min(self.buff_size, response_set.request_len-buffer_len) )
if not new_data:
return False
buffer_len += len(new_data)
# Send required response
for response in response_set.response_list:
try:
connection.sendall(str(response.payload))
except:
return False
有时,我在线上从客户端发送有效负载时出错了
dataOutputStream.write(UtilsManager.serialize(RS.getPayload()));
我得到的错误是:
java.net.SocketException: sendto failed: EPIPE (Broken pipe)
at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:506)
at libcore.io.IoBridge.sendto(IoBridge.java:475)
at java.net.PlainSocketImpl.write(PlainSocketImpl.java:507)
at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:269)
at java.io.DataOutputStream.write(DataOutputStream.java:98)
at java.io.OutputStream.write(OutputStream.java:82)
at com.rgolani.replay.tcp.TCPClientThread.run(TCPClientThread.java:56)
at java.lang.Thread.run(Thread.java:856)
Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe)
at libcore.io.Posix.sendtoBytes(Native Method)
at libcore.io.Posix.sendto(Posix.java:151)
at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
at libcore.io.IoBridge.sendto(IoBridge.java:473)
... 7 more
我知道这有点令人困惑。 Python代码还没有由我编写,并且存在一个没有任何错误的python客户端。我只在我的JAVA代码中收到此错误。
使用Python客户端
if self.sock is None:
self._connect_socket()
self.sock.sendall(tcp.payload)
buffer_len = 0
while tcp.response_len > buffer_len:
data = self.sock.recv( min(self.buff_size, tcp.response_len-buffer_len) )
buffer_len += len(data)
如果您需要更多信息,请与我们联系。
谢谢。
答案 0 :(得分:1)
如果你正在使用setChunkedStreamingMode
然后将其删除然后再看。我想我已经很晚了但这解决了我的问题。你可以使用固定长度的流媒体模式。
答案 1 :(得分:1)
当后端已经关闭连接时,客户端尝试写入连接时发生该错误。
默认情况下,Android将Keep Alive
属性设置为true,并将重用旧的套接字连接,因为在移动环境中建立连接是一项耗费资源的操作(您可以使用fiddler等工具对其进行测试。
尝试将Connection
标头设置为close
或调用System.setProperty("http.keepAlive", "false");
以禁用Keep Alive,从而强制系统创建新连接。
答案 2 :(得分:0)
也许我对你的问题遗漏了一点,但我认为使用这个Java片段会更好:
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
ObjectOutputStream dataOutputStream = null;
ObjectInputStream dataInputStream = null;
try {
if (client.socket == null || !client.socket.isConnected())
client.createSocket();
// Get Input/Output stream for socket
dataOutputStream = new ObjectOutputStream (client.socket.getOutputStream());
dataInputStream = new ObjectInputStream (client.socket.getInputStream());
// Here RS is simple JAVA class that stores information about payload and response length
Log.d("Send", "Sending payload for pair " + RS.getc_s_pair() + " " + RS.getResponse_len());
// You might consider using java.io.Serializable interface with the argument object
dataOutputStream.writeObject(UtilsManager.serialize(RS.getPayload()));
// Notify waiting Queue thread to start processing next packet
if (RS.getResponse_len() > 0) {
Log.d("Response", "Waiting for response for pair " + RS.getc_s_pair() + " of " + RS.getResponse_len() + " bytes");
// Read a java.io.Serializable object from the stream. So you have to write a java.io.Serializable object into the stream.
Object o = dataInputStream.readObject();
}
}
希望这会有所帮助......
答案 3 :(得分:0)
在我的情况下:client.createSocket();不要连接到任何服务器 - 只需创建一个套接字。所以后来我必须client.connect(_sock_sddr_here _);
同样isConnected() - 哑测试,因为它永远是真的。