刷新DataOutputStream

时间:2018-12-18 09:46:02

标签: java

因此,我对套接字和数据流还很陌生...我绝对对这个问题感到困惑。假设其他人可能遇到我遇到的相同问题,我已经花了数小时试图找到解决方案,但是到目前为止,我发现绝对没有任何帮助。

我正在编写一个非常简单的多线程服务器/客户端程序,该程序应该打开serverSocket,并接受来自客户端的连接,并将它们存储在一个简单的arraylist中(一旦我实际收到要发送的消息,我将更改存储过程。 ),然后消息处理程序线程解析该列表,并检查用户是否已写入服务器。如果用户已经写了一些东西,则程序将结果消息显示到控制台。我的程序通过DataOutputStream成功写入服务器套接字,但是当我尝试从服务器端的相应DataInputStream读取时,它说该流为空,并且我的程序将继续循环。我已经检查过DataOutputStream是否通过DataOutputStream.size()接收到数据,并且我尝试从中读取数据的DataInputStream对应于我之前提到的正确的DataOutputStream。

用户代码:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;

public class User {
    private String hashID;
    private Socket connection;
    private static int hashVal = 0;
    DataInputStream consoleInputStream;
    String consoleInput = "";

    public User(Socket conn) throws SocketException {
        hashID = hashUserKey();
        connection = conn;
        connection.setSoTimeout(1500);
        consoleInputStream = new DataInputStream(System.in);
    }

    private static String hashUserKey() { //placeholder for now
        hashVal++;
        return("Guest" + hashVal);
    }

    public Socket getSocket() {
        return this.connection;
    }

    public String getID() {
        return this.hashID;
    }

    public boolean disconnect() {
        try {
            consoleInputStream.close();
            connection.close();
            return true;
        } catch (IOException e) {
            System.err.println(hashID + " was unable to successfully disconnect");
            return false;
        }
    }

    public void startConnection() {
        new Thread() {
            @Override
            public void run() {

                while(!connection.isClosed()) {

                    try {
                        consoleInput = consoleInputStream.readLine();
                        if(consoleInput != null || consoleInput != "") {
                            writeToServer(consoleInput);
                        }
                    } catch (IOException e) {
                        System.err.println("Was not able to read console input");
                    }
                }
                System.out.println("You were disconnected, have a nice day!");
                return;
            }
        }.start();

    }

    private boolean writeToServer(String toWrite) {
        try {
            String msg = hashID + ">>>: " + toWrite;
            DataOutputStream outStream = new DataOutputStream(connection.getOutputStream());
            outStream.writeUTF(toWrite + "\r\n");
            outStream.flush();
            consoleInput = "";
            System.out.println(msg + "\t was written to " + connection.getInetAddress() + ":" + connection.getPort());
            return true;
        } catch (IOException e) {
            System.err.println(hashID + " was unable to write to server");
            return false;
        }
    }

    @Override
    public boolean equals(Object o) {
        User t = (User) o;
        if(t.hashID == this.hashID) {
            return true;
        }
        return false;
    }

}

服务器代码:

import java.net.*;
import java.io.*;
import java.util.*;

public class TestServer {

        private static ServerSocket server;
        private static TestLogger logger;
        private static Thread serverHandlerThread;
        private static Thread messageHandlerThread;
        private static ArrayList<User> users;
        private static volatile boolean hasBeenStopped = false;

        public static boolean startServer(int port) {
            logger = new TestLogger();
            logger.log("Attempting to create default shutdown behavior for server");
            Runtime.getRuntime().addShutdownHook(new Thread() {
                    @Override
                    public void run() {
                        if(!hasBeenStopped) {
                            logger.warn("Server was shut down without running stopServer(), running by default");
                            stopServer();
                        }
                    }
                }
            );
            logger.log("Shutdown behaivor created. Now attempting to set up user database"/*TODO create a real database*/);
            users = new ArrayList<User>();
            logger.log("Attempting to start server");

            try {
                server = new ServerSocket(port);
                logger.log("Server successfully started at " + server.getInetAddress() + ":" + server.getLocalPort() +", now attempting to start user connection handler");
                serverHandlerThread = new Thread() {
                    @Override
                    public void run() {
                        this.setName("serverHandlerThread");
                        while(!server.isClosed()) {
                            try {
                                Socket temp = server.accept();
                                logger.log("Connection accepted from " + temp.getInetAddress());
                                System.out.println("Connection accepted from " + temp.getInetAddress());
                                startUserConnection(new User(temp));
                            } catch (SocketException e) {
                                logger.warn("Server was closed while in accept phase");
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        logger.log(this.getName() + " was stopped, server socket was closed successfully");
                        return;
                    }
                };

                serverHandlerThread.start();
                logger.log("Server thread successfully started, listening for connections on: " + server.getInetAddress().toString() + ":" + port);

                logger.log("Attempting to start message handler thread to read user inputs");
                messageHandlerThread = new Thread() {
                    @Override
                    public void run() {
                        this.setName("messageHandlerThread");
                        while(!server.isClosed()) {
                            if(users.isEmpty()) {
                                continue;
                            }
                            for(int i = 0; i < users.size(); i++) {
                                User temp = users.get(i);
                                try {
                                    System.out.println(new DataInputStream(temp.getSocket().getInputStream()).readUTF());
                                } catch (IOException e) {
                                    System.err.println("Nothing to read from client: " + temp.getID());
                                }
                                try {
                                    Thread.sleep(2000);
                                } catch (InterruptedException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                };

                messageHandlerThread.start();
                return true;
            } catch (IOException e) {
                logger.error("Could not bind server socket to port.");
                return false;
            }

        }

        public static boolean stopServer() {
            logger.log("Started shut down process");
            if(serverHandlerThread == null || !serverHandlerThread.isAlive()) {
                logger.warn("Thread has not been started yet or has already been killed");
                return false;
            }
            else {
                stopAllUserConnections();

                try {
                    server.close();
                    hasBeenStopped = true;
                    while(serverHandlerThread.isAlive()) {

                    }
                    logger.log("Server was successfully shut down");
                    return true;
                } catch (IOException e) {
                    logger.error("Could not close server socket");
                    return false;
                }

            }
        }

        private static void startUserConnection(User user) {
            logger.log("Connected new user from " + user.getSocket().getInetAddress());
            users.add(user);
            System.out.println(user.getID() + " was added to list");
            user.startConnection();
        }

        private static boolean stopUserConnection(User user) {
            logger.log("Attempting to disconnect user, address: " + user.getSocket().getInetAddress());
            for(User u : users) {
                if(u.equals(user)) {
                    u.disconnect();
                    return true;
                }
            }
            logger.warn("Could not find user with address: " + user.getSocket().getInetAddress());
            return false;
        }

        private static boolean stopAllUserConnections() {
            logger.log("Attempting to disconnect all users from the server");
            if(users.isEmpty()) {
                logger.warn("No users available to disconnect");
                return false;
            }
            for(User u : users) {
                u.disconnect();
            }
            users.clear();
            return true;
        }

        public static void main(String args[]) {
            startServer(*the_port*);
            Client c = new Client();
            c.connect("0.0.0.0", *the_port*);
        }
}

客户代码:

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {

    public boolean connect(String serverName, int port) {
        try {
            System.out.println("Attempting to connect");
            Socket sock = new Socket(serverName, port);
            System.out.println("Connected");
            return true;
        } catch (UnknownHostException e) {
            System.err.println("Could not resolve " + serverName + ":" + port);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

因此,正如我在上文中所述,在我尝试读取写入服务器的数据之前,此方法都可以正常工作。不管我做什么,服务器对套接字上的readUTF()的调用始终会抛出IOException,并且使用DataInputStream.available()检查准备读取的字节也将返回0。我最近一次运行的示例输出如下:

Attempting to connect
Connected
Connection accepted from *the_address*
Guest1 was added to list
Nothing to read from client: Guest1
Nothing to read from client: Guest1
Nothing to read from client: Guest1
test
Guest1>>>: test  was written to *the_address:another_port*
Nothing to read from client: Guest1
Nothing to read from client: Guest1
Nothing to read from client: Guest1

我知道我的代码可能已经过优化,我将在稍后进行修复,但是现在,我想知道的是为什么刷新对应的DataOutputStream后DataInputStream为空,以及如何成功发送UTF他们之间的数据。

0 个答案:

没有答案