首页 > 解决方案 > 如何在运行方法之外发送对象?

问题描述

我希望能够使用我的sendMessage()方法向我的客户发送一些东西,同时还等待客户消息(客户应该能够这样做)。我试图在任何地方定义 Socket 和 Streamobjects,但我认为我并不真正了解它们是如何工作的。

    public class Server extends Thread{
private ObjectOutputStream oos;

public void sendMessage(String message){
    try
    {
        oos.writeObject(message);
    } catch (IOException e)
    {
        e.printStackTrace();
    }
}




public void run() {
    try {
        ServerSocket server = new ServerSocket(4444);
        Socket socket = server.accept();
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        this.oos = oos;
        while(true) {
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            String message = (String) ois.readObject();
            System.out.println("Server Received: " + message);
            ois.close();
            socket.close();
        }
    } catch (Exception e) {
    }
}


public class Main {

public static void main(String[] args)
{
   Server s =  new Server();
   s.start();
   new Client().start();
   s.sendMessage("test");

}

编辑

好的,我尝试为每个客户端创建一个线程,但我仍然遇到无法访问 objectoutputstream 的问题...

public class SuperServer {
    private Server s = new Server();

    public void startServer(){
        s.setDaemon(true);
        s.start();

        if(s.isAlive()){
            System.out.println("server started");
        }
    }

    public void sendMessage(String message) throws IOException
    {
        s.handler.sendMessage(message);
    }
}

public class Server extends Thread {
    ServerSocket server;
    Socket socket;


    ServerHandler handler;



    public void run()
    {
        try {
            server = new ServerSocket(4444);


            while (true)
            {
                socket = server.accept();
                ServerHandler serverHandler = new ServerHandler(socket);
                handler = serverHandler;

            }
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }        
}

public class ServerHandler extends Thread {

    protected Socket socket;
    private ObjectOutputStream oos;
    private ObjectInputStream ois;

    public ServerHandler(Socket socket){
        this.socket = socket;
    }

    public void sendMessage(String message) throws IOException
    {
        oos.writeObject(message);
    }

    public void run()
    {
        try(
                ServerSocket server = new ServerSocket(4444);
                Socket socket = server.accept();
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        )
        {
            this.socket = socket;
            this.oos = oos;
            while (true)
            {
                String message = (String) ois.readObject();
                System.out.println("Server Received: " + message);
            }
        } catch (IOException e)
        {
            e.printStackTrace();
        } catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }


}

public class Main {



    public static void main(String[] args) throws IOException
    {
       SuperServer s = new SuperServer();
       s.startServer();

       SuperClient c = new SuperClient();
       c.clientStart();

       Scanner sc = new Scanner(System.in);
        System.out.println("input 1:");
        int a = Integer.parseInt(sc.nextLine());
        if(a == 1) s.sendMessage("test");


    }
}

标签: javamultithreading

解决方案


您错误地使用了线程和套接字。

1)在服务器端,通常您希望为每个与客户端的新连接创建一个新线程,以并行化服务器与其客户端之间的通信。
在这里,您为整个服务器处理创建一个线程......

2)这会产生另一个问题,因为Threads.start()现在不一定要运行线程。所以在这里 :

Server s =  new Server();
s.start();
new Client().start();
s.sendMessage("test");

s.sendMessage("test");可以在之前调用, Server线程Client被执行和终止。所以ObjectOutputStream场可能是静止的null

3) 读取第一条消息后关闭 ServerSocket。
所以即使 s.sendMessage("test");在正确的时间被调用(幸运),这次ois也不会被关闭。null

所以总结一下:

  • 在正确的时间执行事件。
  • 仅在需要时创建新线程。这些不是细节。
  • 如果您仍想发送/接收消息,请不要关闭套接字。

推荐阅读