在Android中获得“连接复位”。

时间:2022-02-19 17:55:27

My app needs to contact the same device it is working on, via http://127.0.0.1/... (a localhost url).

我的应用程序需要联系它正在处理的同一设备,通过http://127.0.0.1/…(本地主机的url)。

For some reason, about 50% of the times (and maybe exactly 50%) when I reach a website there with JSON content, I get the exception:

由于某种原因,当我使用JSON内容访问网站时,大约50%的时间(可能正好是50%),我得到一个例外:

java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)

socketexception: recvfrom失败:ECONNRESET(由peer重新设置的连接)

For the other 50%, I get perfectly good results. I've tried to do polls (and even large delay between polls), but I keep getting the same weird results.

对于另外50%的人来说,我得到了非常好的结果。我试着去做民意调查(甚至在民意调查中也有很大的延迟),但我一直得到相同的奇怪结果。

I've searched the internet and also here, and I'm not sure why it occurs. Does the peer mean that the client has caused it? Why does it happen, and how should i handle it?

我搜索了互联网和这里,我不知道为什么会这样。同行是否意味着客户导致了它?为什么会发生,我该如何处理?

Some websites say that it's a common thing, but I didn't find what's the best thing to do in such cases.

一些网站说这是很常见的事情,但我没有发现在这种情况下最好的做法是什么。

4 个解决方案

#1


18  

Ok, the answer was that it's the server's fault - it had to close the connection after each request.

好的,答案是它是服务器的错误——它必须在每次请求之后关闭连接。

It might be that Android keeps a pool of connections and use the old one or something like that.

可能是Android有一个连接池,使用旧的或类似的连接。

Anyway , now it works.

不管怎样,现在它起作用了。


EDIT: according to the API of HttpURLConnection, this can be solved on the client side too:

编辑:根据HttpURLConnection的API,这也可以在客户端解决:

The input and output streams returned by this class are not buffered. Most callers should wrap the returned streams with BufferedInputStream or BufferedOutputStream. Callers that do only bulk reads or writes may omit buffering. When transferring large amounts of data to or from a server, use streams to limit how much data is in memory at once. Unless you need the entire body to be in memory at once, process it as a stream (rather than storing the complete body as a single byte array or string).

这个类返回的输入和输出流没有缓冲。大多数调用者应该用bufferedputstream或BufferedOutputStream来包装返回的流。只有批量读或写的调用者可以省略缓冲。在将大量数据传输到或从服务器传输时,使用流来限制一次内存中有多少数据。除非您需要整个主体同时处于内存中,否则将其作为流处理(而不是将完整的主体存储为单个字节数组或字符串)。

To reduce latency, this class may reuse the same underlying Socket for multiple request/response pairs. As a result, HTTP connections may be held open longer than necessary. Calls to disconnect() may return the socket to a pool of connected sockets. This behavior can be disabled by setting the http.keepAlive system property to false before issuing any HTTP requests. The http.maxConnections property may be used to control how many idle connections to each server will be held.

为了减少延迟,这个类可以对多个请求/响应对重用相同的底层套接字。因此,HTTP连接可能被打开的时间超过了必要的时间。调用disconnect()可以将套接字返回到连接的套接字池。通过设置http,可以禁用此行为。在发出任何HTTP请求之前,将系统属性保存为false。http。maxConnections属性可以用来控制每个服务器将持有多少空闲连接。

Taken from: developer.android.com/reference/java/net/HttpURLConnection.html

来自:developer.android.com/reference/java/net/HttpURLConnection.html

#2


6  

Try to set this property for your HttpURLConnection before connecting:

在连接之前,尝试为您的HttpURLConnection设置此属性:

conn.setRequestProperty("connection", "close");

This will disable "keep-alive" property which is on by default.

这将禁用默认状态下的“keep-alive”属性。

#3


1  

This is an old thread i know. But this might help someone.

这是我知道的一条旧线。但这可能会对某些人有所帮助。

In my case this error was caused by the .NET WCF (soap) service. One of the objects in the returning result had a DataMember with get{} property but no set{} property.

在我的例子中,这个错误是由。net WCF (soap)服务引起的。返回结果中的一个对象有一个DataMember,其中有一个get{}属性,但没有设置{}属性。

For serialization to occur every DataMember should have both get{} & set{} available. I implemented an empty set{} (empty due to my business rules), and problem was solved.

为了实现序列化,每个数据节点都应该同时具有{}和set{}。我实现了一个空集{}(由于我的业务规则是空的),并且解决了问题。

My scenerio is a specific bad server implementation, but maybe it'll help someone saving time when troubleshooting.

我的scenerio是一个特定的坏服务器实现,但它可能会帮助人们在故障排除时节省时间。

#4


0  

I was having a lot of these Connection reset by peer when I was visiting certain web pages or downloading files (from my app or the Android browser).

当我访问某些网页或下载文件(从我的应用程序或Android浏览器)时,我有很多这样的连接重置。

Turned out it was my 3G carrier that blocked the connections (e.g. downloading an .exe file was forbidden).

原来是我的3G载波阻止了连接(例如,下载.exe文件是被禁止的)。

Do you have the same problem on Wifi ?

你在Wifi上有同样的问题吗?

#1


18  

Ok, the answer was that it's the server's fault - it had to close the connection after each request.

好的,答案是它是服务器的错误——它必须在每次请求之后关闭连接。

It might be that Android keeps a pool of connections and use the old one or something like that.

可能是Android有一个连接池,使用旧的或类似的连接。

Anyway , now it works.

不管怎样,现在它起作用了。


EDIT: according to the API of HttpURLConnection, this can be solved on the client side too:

编辑:根据HttpURLConnection的API,这也可以在客户端解决:

The input and output streams returned by this class are not buffered. Most callers should wrap the returned streams with BufferedInputStream or BufferedOutputStream. Callers that do only bulk reads or writes may omit buffering. When transferring large amounts of data to or from a server, use streams to limit how much data is in memory at once. Unless you need the entire body to be in memory at once, process it as a stream (rather than storing the complete body as a single byte array or string).

这个类返回的输入和输出流没有缓冲。大多数调用者应该用bufferedputstream或BufferedOutputStream来包装返回的流。只有批量读或写的调用者可以省略缓冲。在将大量数据传输到或从服务器传输时,使用流来限制一次内存中有多少数据。除非您需要整个主体同时处于内存中,否则将其作为流处理(而不是将完整的主体存储为单个字节数组或字符串)。

To reduce latency, this class may reuse the same underlying Socket for multiple request/response pairs. As a result, HTTP connections may be held open longer than necessary. Calls to disconnect() may return the socket to a pool of connected sockets. This behavior can be disabled by setting the http.keepAlive system property to false before issuing any HTTP requests. The http.maxConnections property may be used to control how many idle connections to each server will be held.

为了减少延迟,这个类可以对多个请求/响应对重用相同的底层套接字。因此,HTTP连接可能被打开的时间超过了必要的时间。调用disconnect()可以将套接字返回到连接的套接字池。通过设置http,可以禁用此行为。在发出任何HTTP请求之前,将系统属性保存为false。http。maxConnections属性可以用来控制每个服务器将持有多少空闲连接。

Taken from: developer.android.com/reference/java/net/HttpURLConnection.html

来自:developer.android.com/reference/java/net/HttpURLConnection.html

#2


6  

Try to set this property for your HttpURLConnection before connecting:

在连接之前,尝试为您的HttpURLConnection设置此属性:

conn.setRequestProperty("connection", "close");

This will disable "keep-alive" property which is on by default.

这将禁用默认状态下的“keep-alive”属性。

#3


1  

This is an old thread i know. But this might help someone.

这是我知道的一条旧线。但这可能会对某些人有所帮助。

In my case this error was caused by the .NET WCF (soap) service. One of the objects in the returning result had a DataMember with get{} property but no set{} property.

在我的例子中,这个错误是由。net WCF (soap)服务引起的。返回结果中的一个对象有一个DataMember,其中有一个get{}属性,但没有设置{}属性。

For serialization to occur every DataMember should have both get{} & set{} available. I implemented an empty set{} (empty due to my business rules), and problem was solved.

为了实现序列化,每个数据节点都应该同时具有{}和set{}。我实现了一个空集{}(由于我的业务规则是空的),并且解决了问题。

My scenerio is a specific bad server implementation, but maybe it'll help someone saving time when troubleshooting.

我的scenerio是一个特定的坏服务器实现,但它可能会帮助人们在故障排除时节省时间。

#4


0  

I was having a lot of these Connection reset by peer when I was visiting certain web pages or downloading files (from my app or the Android browser).

当我访问某些网页或下载文件(从我的应用程序或Android浏览器)时,我有很多这样的连接重置。

Turned out it was my 3G carrier that blocked the connections (e.g. downloading an .exe file was forbidden).

原来是我的3G载波阻止了连接(例如,下载.exe文件是被禁止的)。

Do you have the same problem on Wifi ?

你在Wifi上有同样的问题吗?