考虑这个(简化的)代码段:
public class Test { // assigned elsewhere InetSocketAddress socketAddress; String socketHost; int socketPort; Socket socket; int COMMAND = 10; int CONNECTION_TIMEOUT = 10 * 1000; int SOCKET_TIMEOUT = 30 * 1000; DataOutputStream dos; DatainputStream dis; protected voID connect() throws IOException, InterruptedException { socket.connect(socketAddress != null ? socketAddress : new InetSocketAddress(socketHost, socketPort), CONNECTION_TIMEOUT); socket.setSoTimeout(SOCKET_TIMEOUT); socket.setTcpNoDelay(true); } voID initializeDataStreams() throws IOException { dos = new DataOutputStream(new bufferedoutputstream(socket.getoutputStream(), socket.getSendBufferSize())); dis = new DatainputStream( new BufferedinputStream( socket.getinputStream(), socket.getReceiveBufferSize())); } voID run() { try { connect(); initializeDataStreams(); sendCommand(COMMAND, true); sendIDAndUsername(true); sendSyncPreference(true); sendBlockedIDs(true); sendheaders(); // reading from 'dis' here // ... } catch (InterruptedException | IOException e){ /* ... */ } } voID sendCommand(int command, boolean buffered) throws IOException { dos.write(command); if (!buffered) { dos.flush(); } } voID sendIDAndUsername(boolean buffered) throws IOException { sendID(true); // always buffered String username = "user name"; dos.writeBoolean(username != null); if (username != null) { dos.writeUTF(username); } if (!buffered) { dos.flush(); } } voID sendID(boolean buffered) throws IOException { dos.writeUTF("user ID"); if (!buffered) { dos.flush(); } } voID sendSyncPreference(boolean buffered) throws IOException { boolean fullSync = true; dos.writeBoolean(fullSync); if (!buffered) { dos.flush(); } } voID sendBlockedIDs(boolean buffered) throws IOException { Set<String> blockedCrocoIDs = new HashSet<>(); ObjectOutputStream oos = new ObjectOutputStream(dos); oos.writeObject(blockedCrocoIDs); if (!buffered) { oos.flush(); } } private voID sendheaders() throws IOException { dos.writeUTF("some string"); dos.writeInt(123); // some other writes... // this should flush everything, right? dos.flush(); }}
我故意用所有方法离开它,以防我在那里犯了一些非常明显的错误.当我执行Test.run()时,有时(真的很难预测到什么时候)似乎sendheaders()中的flush()根本不起作用.
服务器端在接下来的22秒内没有在其ServerSocket.accept()上收到任何东西(不要问我这个号码来自何处,这是神秘的一部分).
我的想法是,我不会在每次传输时调用flush(),但只调用一次,以节省带宽.
那么这段代码有什么问题呢?如何确保对我的流的写入是可靠的/立即的,以便服务器可以尽快读取它?
我也接受回答“没有错”,在这种情况下,它必须是并行完成并影响AndroID上的网络堆栈的东西.
编辑:服务器代码真的没什么特别的:
ListeningThread ListeningThread = new ListeningThread();ListeningThread.start();ListeningThread.join();
然后:
public class ListeningThread extends Thread { private ServerSocket serverSocket; public ListeningThread() { try { // unbound server socket serverSocket = new ServerSocket(); serverSocket.setReuseAddress(true); serverSocket.bind(new InetSocketAddress(NetworkUtil.APP_SERVER_PORT)); } catch (IOException e) { log(e); } } @OverrIDe public voID run() { log("run"); while (serverSocket.isBound() && !isInterrupted()) { try { Socket socket = serverSocket.accept(); new CommandThread(socket).start(); } catch (IOException e) { log(e); } } try { serverSocket.close(); } catch (IOException e) { log(e); } }}
最后:
public class CommandThread extends Thread { private final Socket socket; public CommandThread(Socket socket) { log("CommandThread"); this.socket = socket; } @OverrIDe public voID run() { log("run"); try { socket.setSoTimeout(NetworkUtil.soCKET_TIMEOUT); socket.setTcpNoDelay(true); inputStream is = socket.getinputStream(); int cmd = is.read(); // <========= so actually this is failing switch (cmd) { // handling of the command case COMMAND: new DownloadMessagesThread(socket).start(); break; } } catch (IOException | sqlException e) { log(e); } }}
正如评论中所提到的,我愿意同意对象流的任何错误.但问题是我无法触及(再次,它只是有时,它是非常随机的……)CommandThread的run().因此,除非我遗漏了其他内容,否则Object Streams无法导致这种失败.
编辑2:更正:它不接受()我无法达到,这是第一次读取 *** 作:
03-07 11:22:42.965 00010 CommandThread: CommandThread
03-07 11:22:42.966 00108 CommandThread: run
[… nothing happening …]
03-07 11:23:04.549 00111 DownloadMessagesThread: run
这可能是由于混合了对象流和数据流吗?
解决方法:
您应该验证sendBlockedIDs中的ObjectOutputStream创建不是罪魁祸首.
在混合DataStreams和ObjectStreams时,我已经有了一些协议“死锁”,因为创建Writer / Reader对ObjectStreams意味着一种握手,在混合这些流时可能会失败.
编辑:在再次阅读你的问题时,我意识到我没有回答.所以,是的,它是可靠的.和EJP答案1.
总结以上是内存溢出为你收集整理的java – socket流的flush()的可靠性如何?全部内容,希望文章能够帮你解决java – socket流的flush()的可靠性如何?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)