java.net.SocketException: sendto failed: EPIPE (Broken pipe) on Android
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23357479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.net.SocketException: sendto failed: EPIPE (Broken pipe) on Android
提问by Rajesh Golani
I am trying to read data from server socket from client in Android.
我正在尝试从 Android 客户端从服务器套接字读取数据。
Here are the snippets of code that I'm using:
以下是我正在使用的代码片段:
Client(On Android in JAVA)
客户端(在 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;
}
}
Server (Python)
服务器 (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
Sometimes, I am getting error while I'm sending payload from client on line
有时,当我从客户端在线发送有效负载时出现错误
dataOutputStream.write(UtilsManager.serialize(RS.getPayload()));
Error I'm getting is:
我得到的错误是:
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.access0(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
I know this is little bit confusing. Python code has not been written by me and there exists a python client which works without any errors. I'm getting this error only in my JAVA code.
我知道这有点令人困惑。Python 代码不是我写的,并且存在一个可以正常工作的 Python 客户端。我只在我的 JAVA 代码中收到此错误。
Working Python Client
工作 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)
Please let me know if you need more information.
如果您需要更多信息,请告诉我。
Thank you.
谢谢你。
回答by Yvan781
Maybe i am missing a point with your issue, but i think it would be nicer to use this Java snippet:
也许我在您的问题中遗漏了一点,但我认为使用此 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();
}
}
Hope this helps...
希望这可以帮助...
回答by Sumit Joshi
If you are using setChunkedStreamingMode
then remove it and then see.I think I am so late but this solves my problem.You can use fixed length streaming mode.
如果您正在使用,setChunkedStreamingMode
则将其删除然后查看。我想我来得太晚了,但这解决了我的问题。您可以使用固定长度的流模式。
回答by bardi
That error occurs when the client try to write to a connection when the backend has already closed it.
By default Android set the Keep Alive
property to true and will reuse the old socket connections since establishing a connection is a resource consuming operation in a mobile environment (you can test it with a tool like fiddler).
Try to set the Connection
header to close
or call System.setProperty("http.keepAlive", "false");
in order to disable Keep Alive and thus forcing the system to create a new connection.
当后端已经关闭连接时客户端尝试写入连接时会发生该错误。默认情况下,Android 将该Keep Alive
属性设置为 true 并将重用旧的套接字连接,因为在移动环境中建立连接是一项资源消耗操作(您可以使用类似fiddler的工具对其进行测试)。尝试将Connection
标头设置为close
or callSystem.setProperty("http.keepAlive", "false");
以禁用 Keep Alive,从而强制系统创建新连接。
回答by Alexey Kurilov
In my case: client.createSocket(); don't connect to any server - just create a socket. So later I must client.connect(_sock_sddr_here_);
就我而言:client.createSocket(); 不要连接到任何服务器 - 只需创建一个套接字。所以后来我必须 client.connect(_sock_sddr_here_);
Also isConnected() - dumb test because it's forever true.
还有 isConnected() - 愚蠢的测试,因为它永远是真的。