java socket InputStream在客户端和服务器上挂起/阻塞 [英] java socket InputStream hangs/blocks on both client and server

查看:112
本文介绍了java socket InputStream在客户端和服务器上挂起/阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全部

我最近正致力于一个旨在远程关闭浏览器的小程序。
基本程序如下:

服务器端:

I am recently working on a tiny program aimed to close the browser remotely. The basic procedures are as follow:
Server side:


  1. 创建一个SocketServer到听取某个端口。

  2. 接受连接并创建相应的套接字对象

  3. 从创建的套接字读取InputStream(在此$ b上被阻止) $ b操作)







客户端:


Client side:


  1. 创建一个套接字对象以与服务器建立连接。

  2. 发送命令到通过将
    字节写入OutputStream来关闭服务器端的浏览器。

  3. 通过在
    的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));
    }

}
}



ClientRequest.java

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();
            }
        }
    }
}

和最后, Client.java

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();
}
}

重申问题:


  • 服务器端无法通过在套接字的InputStream对象上调用read(buffer,
    offset,len)来读取命令。阻止。

  • 客户端无法通过在其套接字的InputStream对象上调用read(buffer,
    offset,len)来读取反馈。阻止。

  • 但当我在
    Client.java中注释掉反馈阅读操作时,服务器和客户端都能正常工作。

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

希望有人可以帮助我,非常感谢!

I am wondering what's the hidden causes in those codes ?
Hope someone can help me, thanks a lot !

推荐答案

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

Your socket reading code is reading until EOF. you will not receive EOF until you close the socket. hence, your code never proceeds.

如果您只想在套接字连接上发送单个命令,则在编写命令后关闭OutputStream(使用 Socket.shutdownOutput())。

if you only want to send a single command on the socket connection, then close the OutputStream after writing the command (using Socket.shutdownOutput()).

如果要在单个套接字连接上发送多个命令,则需要提出一种分隔每个命令的方法(这里有简单的例子)。

If you want to send multiple commands on a single socket connection, then you will need to come up with a way of delimiting each command (simple example here).

这篇关于java socket InputStream在客户端和服务器上挂起/阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆