Java套接字在局域网上不工作

Java套接字在局域网上不工作,java,multithreading,sockets,synchronization,Java,Multithreading,Sockets,Synchronization,有两台计算机,A和B,每台计算机都在等待另一台计算机告诉他准备好了,当他们收到信息时,他们将开始做一些事情 public class SyncClientImpl implements SyncClient, Runnable { private Socket s; private String ipAddress; private int port; private boolean otherIsReady; private Thread thread; private OutputStre

有两台计算机,A和B,每台计算机都在等待另一台计算机告诉他准备好了,当他们收到信息时,他们将开始做一些事情

public class SyncClientImpl implements SyncClient, Runnable {

private Socket s;
private String ipAddress;
private int port;
private boolean otherIsReady;
private Thread thread;
private OutputStream os;
private ObjectOutputStream oos;

public Thread getThread() {
    return thread;
}

public void setThread(Thread thread) {
    this.thread = thread;
}

public void start() {
    thread = new Thread(this);
    thread.start();
}

public boolean isOtherIsReady() {
    return otherIsReady;
}

public void setOtherIsReady(boolean otherIsReady) {
    this.otherIsReady = otherIsReady;
}

public Socket getS() {
    if (s == null) {
        try {
            s = new Socket(ipAddress, port);
        } catch (UnknownHostException ex) {
            Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    return s;
}

public void setS(Socket s) {
    this.s = s;
}

public String getIpAddress() {
    return ipAddress;
}

public void setIpAddress(String ipAddress) {
    this.ipAddress = ipAddress;
}

public int getPort() {
    return port;
}

public void setPort(int port) {
    this.port = port;
}

@Override
public void send(Object o, int port, String ipAdrress) {
    try {
        os = this.getS().getOutputStream();
        oos = new ObjectOutputStream(os);
        oos.flush();
        oos.writeObject(o);
        oos.flush();
    } catch (IOException ex) {
        Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
    }
}

@Override
public void update() {
    otherIsReady = true;
}

@Override
public void run() {
    try {
        while (!otherIsReady) {
            try {
                this.send("ready", port, ipAddress);
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        oos.close();
        os.close();
        s.close();
    } catch (IOException ex) {
        Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
    }
}
}
第一个类将消息“ready”发送到服务器,它将停止执行此操作,直到其他人通知它。 将通知它的类是:

public class SyncServerImpl implements SyncServer, Runnable {

private ServerSocket ss;
private Socket s;
private String ipAddress;
private int port;
private InputStream is;
private ObjectInputStream ois;
private boolean confirmReceived;
private Thread thread;
private transient List<Observer> list = new ArrayList<Observer>();
private Object lock;

public boolean isConfirmReceived() {
    return confirmReceived;
}

public void setConfirmReceived(boolean confirmReceived) {
    this.confirmReceived = confirmReceived;
}

@Override
public void setLock(Object lock) {
    this.lock = lock;
}

public void start() {
    thread = new Thread(this);
    thread.start();
}

public Socket getS() {
    if (s == null) {
        try {
            s = this.getSS().accept();
        } catch (UnknownHostException ex) {
            Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    return s;
}

public void setS(Socket s) {
    this.s = s;
}

public String getIpAddress() {
    return ipAddress;
}

public void setIpAddress(String ipAddress) {
    this.ipAddress = ipAddress;
}

public int getPort() {
    return port;
}

public void setPort(int port) {
    this.port = port;
}

public ServerSocket getSS() {
    if (ss == null) {
        try {
            ss = new ServerSocket(port);
        } catch (IOException ex) {
            Logger.getLogger(SyncServerImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    return ss;
}

public void setSS(ServerSocket ss) {
    this.ss = ss;
}

@Override
public void addObserver(Observer observer) {
    list.add(observer);
}

@Override
public void removeObserver(Observer observer) {
    list.remove(observer);
}

@Override
public void notifyObservers() {
    for (Observer observer : list) {
        observer.update();
    }
}

public void receive() {
    try {
        is = this.getS().getInputStream();
        ois = new ObjectInputStream(is);
        String to = (String) ois.readObject();
        if (to.equalsIgnoreCase("ready")) {

            synchronized (lock) {
                confirmReceived = true;
                this.notifyObservers();
                lock.notifyAll();
            }
            System.out.println("packet received");

        }
    } catch (IOException ex) {
        Logger.getLogger(SyncServerImpl.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(SyncServerImpl.class.getName()).log(Level.SEVERE, null, ex);
    }
}

@Override
public void run() {
    try {
        while (!confirmReceived) {
            this.receive();
        }
        ois.close();
        is.close();
        s.close();
        ss.close();
    } catch (Exception ex) {
        Logger.getLogger(SyncServerImpl.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public static void main(String args[]) {
    final Object lock = new Object();
    SyncServerImpl ss = new SyncServerImpl();
    SyncClientImpl sc = new SyncClientImpl();
    ss.setLock(lock);
    ss.addObserver(sc);
    ss.setPort(2002);
    ss.start();


    sc.setIpAddress("192.168.1.101");
    sc.setPort(2002);
    sc.start();

    synchronized (lock) {
        while (!ss.isConfirmReceived()) {
            try {
                lock.wait();
            } catch (InterruptedException ex) {
            }
        }
    }

    System.out.println("Ok");
}
}
此错误看起来与上述错误相同,但描述方式不同


有人知道是什么导致了这个错误吗?

试着简化您的解决方案,看看下面关于套接字编程的文章:

在尝试在两个方向上使用之前,先尝试使它以一种方式工作(尽管我不太清楚是否需要该功能)。现在,同一应用程序中的客户机和服务器线程正在干扰您试图通过网络设置的客户机/服务器对

如果您只想通过套接字发送文本,只需使用BufferedReader和PrintWriter而不是ObjectStreams(如果管理不当,后者可能会导致内存问题)


如果您只想使用连接检查另一个是否准备好,而不是关闭套接字,则可以,但是如果您想保持连接打开,则需要保持OutputStream(而不是套接字本身)以便在线程中进行进一步处理。同样,请查看上面的文章并从中着手。

不要为每次发送创建新的
ObjectOutputStream
。为套接字的生命周期创建一次。同上
ObjectInputStream。
sync.SyncClientImpl send
GRAVE: null
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1864)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1773)
at java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:229)
at tetris.logic.online.sync.SyncClientImpl.send(SyncClientImpl.java:87)
at tetris.logic.online.sync.SyncClientImpl.run(SyncClientImpl.java:106)
at java.lang.Thread.run(Thread.java:695)
sync.SyncClientImpl send
GRAVE: null
java.net.SocketException: Software caused connection abort: socket write error
...
at tetris.logic.online.sync.SyncClientImpl.send(SyncClientImpl.java:87)
at tetris.logic.online.sync.SyncClientImpl.run(SyncClientImpl.java:106)
at java.lang.Thread.run(Thread.java:695)
@Override
public void send(String line, int port, String ipAdrress) {
    try {
        Socket clientSocket = new Socket(ipAddress, port);
        os = clientSocket.getOutputStream();
        PrintWriter out= new PrintWriter(os, true);
        out.println(line);
        out.close();
        clientSocket.close();
    } catch (IOException ex) {
        Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
    }
}