Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java套接字InputStream在客户端和服务器上都挂起/阻塞_Java_Sockets - Fatal编程技术网

java套接字InputStream在客户端和服务器上都挂起/阻塞

java套接字InputStream在客户端和服务器上都挂起/阻塞,java,sockets,Java,Sockets,大家好 我最近正在开发一个小程序,旨在远程关闭浏览器。 基本程序如下: 服务器端: 创建一个SocketServer以侦听某个特定端口 接受连接并创建相应的套接字对象 从已创建的套接字读取InputStream(在此端口上被阻止 操作) 客户端: 创建套接字对象以建立与服务器的连接 通过写入来发送关闭服务器端浏览器的命令 要输出流的字节数 在的InputStream上使用Read()读取来自服务器的反馈 套接字(在此操作中被阻止) 下面的代码: Server.java package so

大家好

我最近正在开发一个小程序,旨在远程关闭浏览器。 基本程序如下:
服务器端:

  • 创建一个SocketServer以侦听某个特定端口
  • 接受连接并创建相应的套接字对象
  • 从已创建的套接字读取InputStream(在此端口上被阻止 操作)

  • 客户端:

  • 创建套接字对象以建立与服务器的连接
  • 通过写入来发送关闭服务器端浏览器的命令 要输出流的字节数
  • 在的InputStream上使用Read()读取来自服务器的反馈 套接字(在此操作中被阻止)

  • 下面的代码:

    Server.java

    package socket;
    
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.NetworkInterface;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Enumeration;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Server {
    
    private static ExecutorService es = Executors.newFixedThreadPool(5);
    
    public static void main(String[] args) throws IOException {
    
        InetAddress targetAddress = null;
        NetworkInterface ni = NetworkInterface.getByName("eth2");
        System.out.println(ni);
        Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
        while(inetAddresses.hasMoreElements()) {
            InetAddress inetAddress = inetAddresses.nextElement();
            if(inetAddress.toString().startsWith("/10")) {
                targetAddress = inetAddress;
                break;
            }
        }
        ServerSocket sSocket = new ServerSocket(11111, 0, targetAddress);
        while(true) {
            System.out.println("Server is running...");
            Socket client = sSocket.accept();
            System.out.println("Client at: " + client.getRemoteSocketAddress());
            es.execute(new ClientRequest(client));
        }
    
    }
    }
    
    package socket;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class ClientRequest implements Runnable {
    
    private Socket client;
    
    public ClientRequest(Socket client) {
        this.client = client;
    }
    
    @Override
    public void run() {
    
        try {
            System.out.println("Handled by: " + Thread.currentThread().getName());
            // get input/output streams for client socket
            InputStream cis = client.getInputStream();
            OutputStream cos = client.getOutputStream();
    
            // buffer size : 1024 ?
            byte[] buffer = new byte[1024];
            int recvSize;
            int totalRecvSize = 0;
            while(-1 != (recvSize = cis.read(buffer, totalRecvSize, 1024 - totalRecvSize))) {
                totalRecvSize += recvSize;
            }
    
            String command = new String(buffer, "utf-8");
            System.out.println("Command from client: " + command);
    
            String commandNative = CommandMap.getNativeCommand(command.trim());
            if(null != commandNative) {
                Process np = Runtime.getRuntime().exec(commandNative);
                InputStream is = np.getInputStream();
                byte[] bufferProcess = new byte[1024];
                int bytesRead;
                int totalBytesRead = 0;
                while(-1 != (bytesRead = is.read(bufferProcess, totalBytesRead, 1024 - totalBytesRead))) {
                    totalBytesRead += bytesRead;
                }
                // give feed back of process output
                cos.write(bufferProcess);
    
                // close process input stream
                is.close();
            } 
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(null != client) {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    package socket;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.nio.charset.Charset;
    
    public class Client {
    
    private static final int BUF_SIZE = 1024;
    
    // feedback message size will not exceed 1024 bytes
    private static final byte[] BUFFER = new byte[BUF_SIZE];
    
    public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
    
        Socket socket = new Socket("10.117.37.176", 11111);
        System.out.println("Connected to Server...");
        OutputStream os = socket.getOutputStream();
        InputStream is = socket.getInputStream();
    
        String command = "kill ie";
        byte[] commandBytes = command.getBytes(Charset.forName("utf-8"));
    
        System.out.println("Send: " + command);
        os.write(commandBytes);
        System.out.println("After send: " + command);
    
        int totalRecv = 0;
        int recvSize;
    
        while(-1 != (recvSize = is.read(BUFFER, totalRecv, BUF_SIZE - totalRecv))) {
            totalRecv += recvSize;
        }
    
        String feedback = new String(BUFFER, "utf-8");
        System.out.println("Feedback: " + feedback);
    
        socket.close();
    }
    }
    
    最后,Client.java

    package socket;
    
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.NetworkInterface;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Enumeration;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Server {
    
    private static ExecutorService es = Executors.newFixedThreadPool(5);
    
    public static void main(String[] args) throws IOException {
    
        InetAddress targetAddress = null;
        NetworkInterface ni = NetworkInterface.getByName("eth2");
        System.out.println(ni);
        Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
        while(inetAddresses.hasMoreElements()) {
            InetAddress inetAddress = inetAddresses.nextElement();
            if(inetAddress.toString().startsWith("/10")) {
                targetAddress = inetAddress;
                break;
            }
        }
        ServerSocket sSocket = new ServerSocket(11111, 0, targetAddress);
        while(true) {
            System.out.println("Server is running...");
            Socket client = sSocket.accept();
            System.out.println("Client at: " + client.getRemoteSocketAddress());
            es.execute(new ClientRequest(client));
        }
    
    }
    }
    
    package socket;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class ClientRequest implements Runnable {
    
    private Socket client;
    
    public ClientRequest(Socket client) {
        this.client = client;
    }
    
    @Override
    public void run() {
    
        try {
            System.out.println("Handled by: " + Thread.currentThread().getName());
            // get input/output streams for client socket
            InputStream cis = client.getInputStream();
            OutputStream cos = client.getOutputStream();
    
            // buffer size : 1024 ?
            byte[] buffer = new byte[1024];
            int recvSize;
            int totalRecvSize = 0;
            while(-1 != (recvSize = cis.read(buffer, totalRecvSize, 1024 - totalRecvSize))) {
                totalRecvSize += recvSize;
            }
    
            String command = new String(buffer, "utf-8");
            System.out.println("Command from client: " + command);
    
            String commandNative = CommandMap.getNativeCommand(command.trim());
            if(null != commandNative) {
                Process np = Runtime.getRuntime().exec(commandNative);
                InputStream is = np.getInputStream();
                byte[] bufferProcess = new byte[1024];
                int bytesRead;
                int totalBytesRead = 0;
                while(-1 != (bytesRead = is.read(bufferProcess, totalBytesRead, 1024 - totalBytesRead))) {
                    totalBytesRead += bytesRead;
                }
                // give feed back of process output
                cos.write(bufferProcess);
    
                // close process input stream
                is.close();
            } 
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(null != client) {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    package socket;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.nio.charset.Charset;
    
    public class Client {
    
    private static final int BUF_SIZE = 1024;
    
    // feedback message size will not exceed 1024 bytes
    private static final byte[] BUFFER = new byte[BUF_SIZE];
    
    public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
    
        Socket socket = new Socket("10.117.37.176", 11111);
        System.out.println("Connected to Server...");
        OutputStream os = socket.getOutputStream();
        InputStream is = socket.getInputStream();
    
        String command = "kill ie";
        byte[] commandBytes = command.getBytes(Charset.forName("utf-8"));
    
        System.out.println("Send: " + command);
        os.write(commandBytes);
        System.out.println("After send: " + command);
    
        int totalRecv = 0;
        int recvSize;
    
        while(-1 != (recvSize = is.read(BUFFER, totalRecv, BUF_SIZE - totalRecv))) {
            totalRecv += recvSize;
        }
    
        String feedback = new String(BUFFER, "utf-8");
        System.out.println("Feedback: " + feedback);
    
        socket.close();
    }
    }
    
    要重申这些问题:

    • 服务器端无法通过调用read(buffer, 套接字的InputStream对象上的偏移量,len)。它会阻塞
    • 客户端无法通过调用read(buffer, 其套接字的InputStream对象上的偏移量,len)。它会阻塞
    • 但当我在中注释掉反馈读取操作时 java,服务器和客户端都能正常工作

    我想知道这些代码中隐藏的原因是什么?

    希望有人能帮助我,谢谢

    您的套接字读取代码正在读取,直到EOF。在关闭插座之前,您不会收到EOF。因此,您的代码永远不会继续

    如果只想在套接字连接上发送一个命令,则在写入命令后关闭OutputStream(使用
    socket.shutdownOutput()


    如果您想在一个套接字连接上发送多个命令,那么您需要找到一种方法来界定每个命令()。

    您正在读取两端的EOS,这是一个糟糕的选择,因为您无法“发送”EOS而不失去在同一连接上发送更多数据的能力。您需要重新设计应用程序协议,以便可以一次读取命令,而无需关闭连接即可完成。例如,发送行、字长前缀、自描述协议(如XML或Java对象序列化)或任何可以通过DataInputStream读取而不依赖EOFEException的内容。

    感谢您的精彩回答!但是仍然存在一个问题,客户端希望获得一些反馈,在我的例子中,反馈应该是本机命令的输出(旨在关闭浏览器)。如果我添加os.close(),当我在InputStream上调用read()方法时,将抛出一个SocketException,并显示消息“socket closed”,我如何处理这个问题?非常感谢。@destiny1020-你试过我的建议了吗?关闭outputstream独立于关闭inputstream。是的,我已经尝试了您的建议,我在Client.java中的os.write()之后添加了一行os.close()。但是当我尝试调用in.read()方法时有一个例外:socketclosed,可能close底层OutputStream会间接关闭Socket连接?我对此感到困惑。谢谢你的回复!我用自己的close()方法关闭输出流,实际上应该调用socket.shutdownOutput(),我已经弄明白了。谢谢你的建议,太棒了@destiny1020-啊,很抱歉,我会更新我的答案。我认为直接关闭outputstream是实现这一点的方法。我已经有一段时间没有使用套接字了。谢谢你的建议,我的应用程序确实存在一些设计问题。非常感谢。