【问题标题】:Java serversocket control synchronization issueJava serversocket控制同步问题
【发布时间】:2013-01-12 06:48:25
【问题描述】:

我正在使用一些 java 来创建一个小型客户端来监控网络。对于网络上的每个节点,我都运行一个客户端,还运行一个 ServerSocket 来监听传入的连接。我写的代码似乎挂在了 ServerSocket.listen() 方法上。我正在尝试运行一些需要启动服务器套接字的测试代码,并在设置完成后向其发送一些数据。基本上我的问题是这样的:

客户端.java

/*snip*/
public void listen(){
    try{
        ServerSocket server = new ServerSocket(1234);
        server.listen();
        Socket client = server.accept()
        System.out.println("got connection");
        ... do stuff
    catch(IOException ex){
        ex.printStackTrace();
    }
}

TestClient.java

/*snip*/
Client client = new Client();
client.listen();
System.out.println("client constructed, waiting for connection");
Socket sock = new Socket("localhost", 1234);
... do stuff

java ServerSocket 的每个其他示例都将它放在自己的类中,只是为了循环自身并在无限循环中运行。如果可能的话,我试图让服务器从另一个主要方法执行。据我所知,问题在于 client.listen() 方法永远不会完成,因为套接字永远不会获得它的连接。我尝试在 TestClient 中执行该行代码后建立连接:在 eclipse 中,println 都不会打印到输出中。有没有另一种方法可以编写控制结构来巧妙地处理这个问题?

【问题讨论】:

  • 我不明白你想要达到什么目的。您的客户端实际上是一个服务器,它会阻塞直到收到连接。所以在调用server.accept() 之后不会执行任何操作,除非您从另一个线程或另一个进程连接到此服务器套接字。
  • 我想要做的是避免有一个我必须单独执行以监听连接的类。不幸的是,我还没有看到任何不需要在一个程序中执行服务器,然后使用另一个程序发送数据的 java 程序。我希望能够从一个测试程序中做到这两点。换句话说,我希望客户端以某种方式掩盖 listen() 方法,即使它还没有连接。
  • 然后在同一个测试应用的另一个线程中实现客户端。
  • 我仍然不确定那会是什么样子。在这个测试程序中,我将有某种 startserver();然后 startclient() ?我看不出它会如何超出服务器在完成方法之前等待传入连接的点。
  • 在启动服务器之前启动客户端线程,或者在两个不同的线程中同时启动服务器和客户端。或者只在不同的线程中启动服务器并将客户端留在主线程中。

标签: java controls serversocket


【解决方案1】:

也许您正在寻找这样的东西?您可以让服务器套接字在单独的线程中运行

package test;

import java.net.*;

public class Clerver {

    private ServerSocket serverSocket;
    private int listenPort;
    private Thread listenerThread;

    public Clerver(int listenPort) {
        this.listenPort = listenPort;
    }

    public void runIt() throws Exception {

        this.serverSocket = new ServerSocket(listenPort);
        this.listenerThread = new Thread() {
            public void run() {
                synchronized (Clerver.this) {
                    Clerver.this.notify();
                }
                try {
                    Socket clientSocket = Clerver.this.serverSocket.accept();
                    receiveDataOnServer(clientSocket);
                    clientSocket.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        };
        this.listenerThread.start();
        synchronized (this) {
            this.wait();
        }
        Socket sock = new Socket("localhost", listenPort);
        sendDataFromClient(sock);
        receiveDataFromServer(sock);
        System.out.println(">> All done!");
        listenerThread.join();
        System.out.println(">> Bye Bye!");
    }

    private void sendDataFromClient(Socket sock) throws Exception {
        sock.getOutputStream().write("Hello".getBytes());
        System.out.println(">> Sent HELLO");
    }

    private void receiveDataFromServer(Socket sock) throws Exception {
        byte[] buf = new byte[1024];
        int bread = sock.getInputStream().read(buf);
        String response = new String(buf, 0, bread);
        System.out.println("<< RESPONSE from SERVER: " + response);
    }

    private void receiveDataOnServer(Socket sock) throws Exception {

        byte[] buf = new byte[1024];
        int bread = sock.getInputStream().read(buf);
        String response = new String(buf, 0, bread);
        System.out.println(">> Received on Server : " + response);
        sock.getOutputStream().write("WORLD".getBytes());
        System.out.println(">> SERVER sent response back");
    }

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Clerver c = new Clerver(1234);
        c.runIt();

    }

}

【讨论】:

  • 效果很好,感谢您的帮助。关于多线程以及如何实现线程,我还有很多东西要学习。你给了我一个了解更多的好机会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-01
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多