簡體   English   中英

連接到服務器,發送字符串並接收對象-BufferedReader不“就緒”嗎?

[英]Connecting to a Server, sending a string and receiving an object - BufferedReader not 'ready'?

服務器:

    public Server() {
    gui = new GUI();
    try {
        socket = new ServerSocket(2000);
        while (true) {
            Socket client = socket.accept();
            gui.append("Client accepted.");
            if (inetAddrFound(client.getInetAddress().getHostName())) {
                Thread thread = new Thread(new IncomingClient(client));
                threads.put(client, thread);
                thread.start();
            }

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

public class IncomingClient implements Runnable {

    BufferedReader reader;
    Socket sock;

    public IncomingClient(Socket socket) {
        gui.append("Incoming socket class instantiated.");
        try {
            this.sock = socket;
            InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
            reader = new BufferedReader(streamReader);
        } catch (Exception e) {
            for (StackTraceElement s : e.getStackTrace()) {
                gui.append(s.toString());
            }
        }
    }

    @Override
    public void run() {
        String message;
        try {
            while (true) {
                gui.append("Trying to see if reader.readLine == null");
                if (!reader.ready()) {
                    System.out.println("Reader is not ready.");
                    continue;
                }
                if ((message = reader.readLine()) != null && !Thread.currentThread().isInterrupted()) {
                    System.out.println("Reader is not null.");
                    System.out.println("Message = " + message);
                    gui.append(message);
                    if (idFound(message)) {
                        ObjectOutputStream stream = (ObjectOutputStream) sock.getOutputStream();
                        stream.writeObject(spooker);
                        stream.close();
                        threads.get(sock).interrupt();
                        threads.remove(sock);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

客戶端:

private void connect() {
    try {
        socket = new Socket(decode(ADDR), Integer.parseInt(decode(PORT)));
        ois = new ObjectInputStream(socket.getInputStream());
        writer = new PrintWriter(socket.getOutputStream());
        writer.println(String.valueOf(encode(getMotherboardSN())));
        writer.flush;
        writer.close;
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public class IncomingSpookerObject implements Runnable {

    @Override
    public void run() {
        SpookerObject object;
        try {
            while ((object = (SpookerObject) ois.readObject()) != null && !Thread.currentThread().isInterrupted()) {
                spooker = (SpookerObject) ois.readObject();
                thread.interrupt();
                System.out.println(spooker.getX());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我的目的是連接到服務器,將用戶cpu id(每台計算機的唯一標識符)發送到服務器(cpu id是字符串),服務器將讀取cpu id,如果用戶已注冊(例如,如果他們的cpu id在數據庫上),然后它將向他們發送一個對象(Spooker對象)。

Spooker對象是一個僅包含int x = 4的測試對象,以及一個返回x,getX()的方法。

我嘗試執行此操作的原因是為了幫助防止軟件泄漏。 將來,spokeer對象將包含啟動客戶端軟件的信息(例如GUI大小,GUI標題,字符串值等)。 這將使軟件在連接到服務器並檢索回特定信息時更難以泄漏。

我希望我盡可能清楚。

阿奇

編輯-更新的服務器對象。

服務器輸出-

客戶接受。 實例化傳入的套接字類。 嘗試查看reader.readLine == null

讀者尚未准備就緒。 讀者尚未准備就緒。 讀者尚未准備就緒。 讀者尚未准備就緒。 讀者尚未准備就緒。 讀者尚未准備就緒。

它會連續打印出來-為什么讀者從未准備好?

編輯; 添加:

writer.println writer.flush(); writer.close();

您沒有發送帶有客戶端數據的CR,因此就服務器而言,尚沒有完整的行可供讀取。 嘗試將writer.write()更改為writer.println()

我設法弄清楚了。 我不得不使用object = ois.readObject(); 對象實例

不是ois.readObject instanceOf

等等

對不起,簡短的回答,很忙。

服務器正在嘗試讀取永無止境的行。 在您的connect方法中,您應該關閉輸出流。

更新

這是一個有效的例子。 實際上,不得關閉輸出流,因為它將關閉底層套接字。

服務器:

public class Server {
    private static final Logger LOG = Logger.getLogger(Server.class.getName());

    public static void main(String[] args) {
    int port = args.length > 0 ? Integer.parseInt(args[0]) : 2000;
    try (ServerSocket socket = new ServerSocket(port)) {
            while (true) {
                Socket client = socket.accept();
                System.out.println("Client accepted.");
                Thread thread = new Thread(new IncomingClient(client));
                thread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static class IncomingClient implements Runnable {
        private final Socket sock;
        private final SpookerObject spooker = new SpookerObject();

        public IncomingClient(Socket socket) {
            System.out.println("Incoming socket class instantiated.");
            this.sock = socket;
        }

        @Override
        public void run() {
            try (InputStream istream = sock.getInputStream();
                    Reader reader = new InputStreamReader(istream);
                    BufferedReader in = new BufferedReader(reader);
                    OutputStream ostream = sock.getOutputStream();
                    ObjectOutputStream out = new ObjectOutputStream(ostream)) {
                String message = in.readLine();
                if (message != null && idFound(message)) {
                    while (!Thread.currentThread().isInterrupted()
                            && sock.isConnected()) {
                        System.out.println("Reader is not null.");
                        System.out.println("Message = " + message);
                        out.writeObject(spooker);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    sock.close();
                } catch (IOException ex) {
                    LOG.log(Level.SEVERE, null, ex);
                }
            }
        }

        private boolean idFound(String id) {
            return "abcdef".equals(id);
        }
    }
}

客戶:

public class Client implements Closeable {
    private static final Logger LOG = Logger.getLogger(Client.class.getName());

    private final Socket socket;
    private final ObjectInputStream ois;

    public static void main(String[] args) {
        try {
            InetAddress server = InetAddress.getByName(args[0]);
            int port = Integer.parseInt(args[1]);
            String cpuId = args[2];
            try (Client client = new Client(server, port, cpuId)) {
                for (int i = 0; i < 3; ++i) {
                    System.out.println(client.readSpooker());
                }
            }
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
    }

    public Client(InetAddress address, int port, String cpuId)
            throws IOException {
        boolean ok = false;
        socket = new Socket(address, port);
        try {
            OutputStream stream = socket.getOutputStream();
            Writer writer = new OutputStreamWriter(stream, "UTF-8");
            PrintWriter out = new PrintWriter(writer);
            out.println(cpuId);
            out.flush();
            ois = new ObjectInputStream(socket.getInputStream());
            ok = true;
        } finally {
            if (!ok) {
                socket.close();
            }
        }
    }

    @Override
    public void close() throws IOException {
        try {
            if (ois != null) {
                ois.close();
            }
        } finally {
            socket.close();
        }
    }

    public SpookerObject readSpooker() throws IOException {
        try {
            return (SpookerObject)ois.readObject();
        } catch (ClassNotFoundException ex) {
            LOG.log(Level.SEVERE, null, ex);
            throw new IOException(ex.getMessage());
        }
    }
}

只需刪除ready()測試並continue 沒有任何意義。 您只是自旋循環,直到至少一個字節可用於讀取而沒有阻塞,然后您很可能還是阻塞了readLine() ,因為它將阻塞直到可以讀取整行為止。

您還需要確定是否要發送線或對象。 您不能通過同一個套接字來做這兩個事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM