【问题标题】:Simple socket I/O issue...or is it? [closed]简单的套接字 I/O 问题……是吗? [关闭]
【发布时间】:2012-01-03 09:01:17
【问题描述】:

在下面的代码中,DisSemHelper 尝试与所有其他正在运行的 DisSemHelper 进程进行通信,包括它自己。请不要质疑我的动机,除非有什么明显的。 ConnectionListener 线程(在构造函数中启动)侦听来自 DisSemHelpers 的连接,并且构造函数启动连接。问题是,我无法让基本的 readLine() 工作:它会导致 ConnectionListener 挂起。我只需要它来阅读一行。如您所见(已注释掉),我也循环尝试了它,但什么也没有。请帮忙!

已解决:我忘记了 autoflush (doink) 这是应该存在的,请注意“真实”:

PrintWriter out = new PrintWriter(helperSocket.getOutputStream(), true);

问题代码:

public class DisSemHelper extends Thread {
private int id;
private int semaphore;
private Clock clock;

private Vector<Integer> connectedHelpers;
private Vector<Socket> helperSockets;
private int localPort;

private int receivedSender;
private String receivedOperation;
private int receivedTimestamp;

/**
 * @throws IOException 
 */
public DisSemHelper(int id) throws IOException {
    this.id = id;
    this.semaphore = 0;
    this.clock = new Clock();
    this.connectedHelpers = new Vector<Integer>();
    this.helperSockets = new Vector<Socket>();
    this.receivedSender = -1;
    this.receivedOperation = null;
    this.receivedTimestamp = -1;
    this.localPort = Common.portMap.get(id);

    new ConnectionListener().start();

    /* Create and store connections to all helpers */
    for (int i=0; i < Common.NUM_HELPERS; i++) {
        Socket helperSocket = null;

        /* If not already connected with helper i */
        if (!this.connectedHelpers.contains(i)) {

            /* Retry connecting every second until target helper socket is ready */
            Exception e = new ConnectException();
            while (helperSocket == null) {
                try {
                    Thread.sleep(1000);
                    helperSocket = new Socket("localhost", Common.portMap.get(i));
                } catch (ConnectException ce) {
                    e = ce;
                } catch (UnknownHostException uhe) {
                    uhe.printStackTrace();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                } catch (InterruptedException ie) {
                    e.printStackTrace();
                }
            }

            PrintWriter out = new PrintWriter(helperSocket.getOutputStream());
            out.println("" + id);

            this.connectedHelpers.add(i);

            this.helperSockets.add(helperSocket);
            System.out.println("Helper " + id + " added socket from outgoing: local port: " + helperSocket.getLocalPort() + " remote port: " + helperSocket.getPort());
        }
    }

    System.out.println(this.helperSockets);
}

private class ConnectionListener extends Thread {
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(Common.portMap.get(id));

            /* Listen for connections from other helpers */
            while (helperSockets.size() < Common.NUM_HELPERS) {
                Socket helperSocket = serverSocket.accept();
                BufferedReader in = new BufferedReader(new InputStreamReader(helperSocket.getInputStream()));

//                      String inLine;
//                  int connectedHelper = -1;
//                  while ((inLine = in.readLine()) != null) {
//                      connectedHelper = Integer.parseInt(inLine);
//                  }

                int connectedHelper = Integer.parseInt(in.readLine());
                System.out.println("Received helper ID");

                if (!connectedHelpers.contains(connectedHelper)) {
                    connectedHelpers.add(connectedHelper);

                    helperSockets.add(helperSocket);
                    System.out.println("Helper " + id + " added socket from incoming: local port: " + helperSocket.getLocalPort() + " remote port: " + helperSocket.getPort());
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

【问题讨论】:

  • 离题,但在构造函数中启动线程不是一个好主意,因为线程可能在对象完全构造之前启动。
  • 这段代码 `while (helperSockets.size()
  • @MeBigFatGuy 抱歉,在其中添加了一个 accept() 行。
  • @bbarre 抱歉我的无知,但什么是“常见”?
  • 问题:我忘记在输出流上设置自动刷新。我发誓我再也不会这样做了。谢谢。

标签: java sockets io


【解决方案1】:

出现这样的错误是很常见的。原因可能是由于内容被拆分的方式,以及连接被解释为打开或关闭的方式。

这里对您的问题的一些解决方案有很好的解释:Java, sockets, BufferedReader, and readline hang ... :(

特别要注意关于“分块”的部分。我以前也遇到过这个错误——它非常邪恶。

添加:对您的解决方案的回应

作为对解决方案的回应,关于 autoflush :这很有意义。通过不刷新,很可能是数据根本没有被写出到流中。

【讨论】:

    【解决方案2】:

    您将客户端创建的套接字传递到服务器端,而不是在服务器中侦听传入客户端。在我看来你应该使用

     Socket clientSocket = serverSocket.accept();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-24
      • 2011-09-20
      • 2011-10-25
      • 2023-03-17
      • 1970-01-01
      • 2012-07-29
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多