简单的套接字I / O问题......或者是它?

时间:2011-11-21 21:49:34

标签: java sockets io

在下面的代码中,DisSemHelper尝试与所有其他正在运行的DisSemHelper进程通信,包括它自己。除非有什么东西是明显的,否则请不要质疑我的动机。 ConnectionListener线程(在构造函数中启动)侦听来自DisSemHelpers的连接,构造函数启动连接。问题是,我无法使基本的readLine()工作:它导致ConnectionListener挂起。我只需要阅读一条frickin线。正如你所看到的(已注释掉)我也在一个循环中尝试了它而没有任何东西。求救!

解决:我忘了autoflush( doink )这应该是什么,请注意'true':

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();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

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

这里有一些解决方案可以解决您的问题:Java, sockets, BufferedReader, and readline hang ... :(

特别要注意关于“分块”的部分。我之前有过这个错误 - 它非常邪恶。

已添加:对您的解决方案的回复

对于解决方案,关于autoflush:这是完全合理的。通过不刷新,可能只是数据没有写入流。

答案 1 :(得分:0)

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

 Socket clientSocket = serverSocket.accept();