在Java附近的几个Android设备中共享序列化对象的最佳方法
我是一名长期程序员,但对Android Tablet编程和Java来说是新手。我目前正在尝试从具有有限的UDP功能的设备上显示多个平板电脑上的数据。该UDP设备一次只能与一台平板电脑进行交谈,我现在有一台平板电脑可以成功通信,但是我的困难是试图与其他平板电脑共享此数据。所有这些平板电脑都运行了同一应用程序,设置了哪个平板电脑可以处理与UDP设备的通信。所选平板电脑还运行TCP服务器,而其他平板电脑运行匹配的TCP客户端。我从TCP通信中需要的所有内容都是为服务器发送一个自定义的序列化对象,该对象包含平板电脑所需的所有数据,以每100ms的定期速率定期速率。
经过大量的Google搜索,stackoverflow搜索和实验,我现在正在运行以下代码。服务器平板电脑一次调用starttxserver启动该过程,而其余平板电脑每100ms定期调用RunrxClient。
private void StartTxServer() throws IOException
CustomSerial localdata;
ServerSocket server = null;
try {
server = new ServerSocket(TCP_Port) // TCP_Port is a constant int telling the port number
while(Server_Active) { // ServerActive is a boolean
Socket socket = server.accept();
InputStream streamin = socket.getInputStream();
ObjectOutputStream streamout = new ObjectOutputStream(socket.getOutputStream());
byte[] buffer = new byte[1024];
int bytes;
bytes = streamin.read(buffer);
// The following line creates a current copy of my custom serializable object.
localdata = customdata.ConvertToSerial();
streamout.writeObject(localdata);
streamin.close();
streamout.close();
socket.close();
}
} catch (IOException e) {
Log.e("TCP_Server", "Server ERROR: ".concat(e.getMessage()));
e.printStackTrace();
} finally {
server.close();
}
if(Server_Active) {
Log.i("TCP_Server", "Triggering a function restart");
final Runnable restartserver = new Runnable() {
@Override
public void run() {
try {
StartTxServer();
} catch (IOException e) {
e.printStackTrace();
}
}
};
threads.execute(restartserver);
}
}
private void RunRxClient() throws IOException {
CustomSerial localdata;
Socket socket = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
// IP_MasterAddressLocal is a constant IP string, which the server tablet needs to have
// as a static address in order to work with the UDP device.
// TCP_Port is the constant int already referred to in the server function.
socket = new Socket(IP_MasterAddressLocal, TCP_Port);
socket.setSoTimeout(1000);
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
oos.writeObject("R"); // Only one byte for efficiency. Stands for "Request Data".
localdata = (CustomSerial) ois.readObject();
customdata.ConvertFromSerial(localdata); // Loads data into non-serialized object for display.
} catch (IOException | ClassNotFoundException e) {
Log.e("TCP_Client", "ERROR: ".concat(e.getMessage()));
e.printStackTrace();
} finally {
socket.close();
oos.close();
ois.close();
}
}
使用此代码,服务器端似乎成功运行,没有任何错误。但是,当我将客户端平板电脑连接到我的PC时,我在Android Studio LogCat中看到大多数通信尝试失败。通常,我会遇到“ Econnreset”错误,尽管有时我会看到“ Epipe”错误。一条消息会不时成功地通过,而不会设置任何错误。发生这种情况时,客户端平板电脑的屏幕正确更新,证明我的序列化和避免程序是否正常工作。但是,客户平板电脑的屏幕非常“生!”,并且随着成功的数据接收数量少,其更新不一致。当我开发此代码时,平板电脑就在桌子上彼此相邻,因此它们之间的Wi-Fi连接不应该是问题。示例错误消息的全文如下。
E/TCP_Server: ERROR: java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer)
W/System.err: java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer)
W/System.err: at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:515)
W/System.err: at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
W/System.err: at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
W/System.err: at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
W/System.err: at java.io.DataOutputStream.write(DataOutputStream.java:98)
W/System.err: at java.io.ObjectOutputStream.writeNewString(ObjectOutputStream.java:1429)
W/System.err: at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1637)
W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
W/System.err: at com.ntt.coursetracker.WiFiService.RunRxClient(WiFiService.java:2398)
W/System.err: at com.ntt.coursetracker.WiFiService.StartTx(WiFiService.java:2296)
W/System.err: at com.ntt.coursetracker.WiFiService.access$200(WiFiService.java:48)
W/System.err: at com.ntt.coursetracker.WiFiService$10.run(WiFiService.java:2268)
W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err: at java.lang.Thread.run(Thread.java:818)
W/System.err: Caused by: android.system.ErrnoException: sendto failed: ECONNRESET (Connection reset by peer)
W/System.err: at libcore.io.Posix.sendtoBytes(Native Method)
W/System.err: at libcore.io.Posix.sendto(Posix.java:206)
W/System.err: at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:513)
W/System.err: ... 19 more
E/TCP_Server: ERROR: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
W/System.err: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
W/System.err: at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:515)
W/System.err: at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
W/System.err: at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
W/System.err: at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
W/System.err: at java.io.DataOutputStream.write(DataOutputStream.java:98)
W/System.err: at java.io.ObjectOutputStream.writeNewString(ObjectOutputStream.java:1429)
W/System.err: at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1637)
W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
W/System.err: at com.ntt.coursetracker.WiFiService.RunRxClient(WiFiService.java:2398)
W/System.err: at com.ntt.coursetracker.WiFiService.StartTx(WiFiService.java:2296)
W/System.err: at com.ntt.coursetracker.WiFiService.access$200(WiFiService.java:48)
W/System.err: at com.ntt.coursetracker.WiFiService$10.run(WiFiService.java:2268)
W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err: at java.lang.Thread.run(Thread.java:818)
W/System.err: Caused by: android.system.ErrnoException: sendto failed: EPIPE (Broken pipe)
W/System.err: at libcore.io.Posix.sendtoBytes(Native Method)
W/System.err: at libcore.io.Posix.sendto(Posix.java:206)
W/System.err: at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:513)
W/System.err: ... 19 more
是否有一个简单的修复程序可以摆脱这些错误?我尝试重写我的功能以匹配其他许多Stackoverflow页面的示例代码,但错误持续存在。另外,还有一种更简单的方法吗?服务器可以在不被提示的情况下定期发送数据,而在范围内的任何客户都默默地聆听?我对任何其他建议开放,以获取将我的序列化数据获取到客户端平板电脑的最佳方法。
I am a long-time programmer, but fairly new to Android tablet programming and java. I am presently attempting to display data on multiple tablets from a device with a limited UDP capability. This UDP device can only talk to one tablet at a time, and I have a tablet successfully communicating with it now, but my difficulty is trying to share this data with the other tablets. All of these tablets are running the same app, with a setting to tell which tablet handles the communication with the UDP device. The selected tablet also runs a TCP server, while the others run a matching TCP client. All that I need from this TCP communication is for the server to send the clients a custom serialized object, which contains all of the data that the tablets need, at a periodic rate of once every 100ms.
After a lot of google searches, stackoverflow searches, and experimentation, I am now running the following code. The server tablet calls StartTxServer once to start the process, while the rest of the tablets call RunRxClient periodically every 100ms.
private void StartTxServer() throws IOException
CustomSerial localdata;
ServerSocket server = null;
try {
server = new ServerSocket(TCP_Port) // TCP_Port is a constant int telling the port number
while(Server_Active) { // ServerActive is a boolean
Socket socket = server.accept();
InputStream streamin = socket.getInputStream();
ObjectOutputStream streamout = new ObjectOutputStream(socket.getOutputStream());
byte[] buffer = new byte[1024];
int bytes;
bytes = streamin.read(buffer);
// The following line creates a current copy of my custom serializable object.
localdata = customdata.ConvertToSerial();
streamout.writeObject(localdata);
streamin.close();
streamout.close();
socket.close();
}
} catch (IOException e) {
Log.e("TCP_Server", "Server ERROR: ".concat(e.getMessage()));
e.printStackTrace();
} finally {
server.close();
}
if(Server_Active) {
Log.i("TCP_Server", "Triggering a function restart");
final Runnable restartserver = new Runnable() {
@Override
public void run() {
try {
StartTxServer();
} catch (IOException e) {
e.printStackTrace();
}
}
};
threads.execute(restartserver);
}
}
private void RunRxClient() throws IOException {
CustomSerial localdata;
Socket socket = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
// IP_MasterAddressLocal is a constant IP string, which the server tablet needs to have
// as a static address in order to work with the UDP device.
// TCP_Port is the constant int already referred to in the server function.
socket = new Socket(IP_MasterAddressLocal, TCP_Port);
socket.setSoTimeout(1000);
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
oos.writeObject("R"); // Only one byte for efficiency. Stands for "Request Data".
localdata = (CustomSerial) ois.readObject();
customdata.ConvertFromSerial(localdata); // Loads data into non-serialized object for display.
} catch (IOException | ClassNotFoundException e) {
Log.e("TCP_Client", "ERROR: ".concat(e.getMessage()));
e.printStackTrace();
} finally {
socket.close();
oos.close();
ois.close();
}
}
With this code, the server side seems to run successfully with no errors noted. But when I connect the client tablet to my PC, I see in the Android Studio Logcat that most of the attempts at communication fail. Usually I get an "ECONNRESET" error, though sometimes I see an "EPIPE" error instead. From time to time, one message gets through successfully without setting either error. When that happens, the client tablet's screen updates correctly, proving that my serialization and deserialization routines work properly. But the client tablet's screen is quite "jerky", with inconsistent updates as would be expected with the low number of successful data receptions. As I develop this code, the tablets are right next to each other on a desk, so Wi-Fi connectivity between them should not be an issue. The full text of sample error messages are below.
E/TCP_Server: ERROR: java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer)
W/System.err: java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer)
W/System.err: at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:515)
W/System.err: at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
W/System.err: at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
W/System.err: at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
W/System.err: at java.io.DataOutputStream.write(DataOutputStream.java:98)
W/System.err: at java.io.ObjectOutputStream.writeNewString(ObjectOutputStream.java:1429)
W/System.err: at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1637)
W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
W/System.err: at com.ntt.coursetracker.WiFiService.RunRxClient(WiFiService.java:2398)
W/System.err: at com.ntt.coursetracker.WiFiService.StartTx(WiFiService.java:2296)
W/System.err: at com.ntt.coursetracker.WiFiService.access$200(WiFiService.java:48)
W/System.err: at com.ntt.coursetracker.WiFiService$10.run(WiFiService.java:2268)
W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err: at java.lang.Thread.run(Thread.java:818)
W/System.err: Caused by: android.system.ErrnoException: sendto failed: ECONNRESET (Connection reset by peer)
W/System.err: at libcore.io.Posix.sendtoBytes(Native Method)
W/System.err: at libcore.io.Posix.sendto(Posix.java:206)
W/System.err: at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:513)
W/System.err: ... 19 more
E/TCP_Server: ERROR: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
W/System.err: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
W/System.err: at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:515)
W/System.err: at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
W/System.err: at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
W/System.err: at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
W/System.err: at java.io.DataOutputStream.write(DataOutputStream.java:98)
W/System.err: at java.io.ObjectOutputStream.writeNewString(ObjectOutputStream.java:1429)
W/System.err: at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1637)
W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
W/System.err: at com.ntt.coursetracker.WiFiService.RunRxClient(WiFiService.java:2398)
W/System.err: at com.ntt.coursetracker.WiFiService.StartTx(WiFiService.java:2296)
W/System.err: at com.ntt.coursetracker.WiFiService.access$200(WiFiService.java:48)
W/System.err: at com.ntt.coursetracker.WiFiService$10.run(WiFiService.java:2268)
W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err: at java.lang.Thread.run(Thread.java:818)
W/System.err: Caused by: android.system.ErrnoException: sendto failed: EPIPE (Broken pipe)
W/System.err: at libcore.io.Posix.sendtoBytes(Native Method)
W/System.err: at libcore.io.Posix.sendto(Posix.java:206)
W/System.err: at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:513)
W/System.err: ... 19 more
Is there a simple fix which would get rid of these errors? I have tried re-writing my functions to match the sample code of plenty of other stackoverflow pages, but the errors persist. Alternatively, is there an easier way to do this? Could the server simply send out data periodically without being prompted, while any clients in range silently listen? I am open to any other suggestions for the best way to get my serialized data to the client tablets.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论