从远程服务器读取并连续写入远程服务器

时间:2015-07-18 09:53:51

标签: java tcp

我希望我的客户端不断读取/写入远程服务器上的日志文件。 我这样做的方法是将tail -f /root/log.txt的输出从我的远程服务器传递给我的客户端。

我遇到了两个问题

  • 我的服务器正在执行命令,但我的客户端没有收到输出。
  • 即使我使用了线程
  • ,也只有一个客户端可以连接到服务器

Client.java

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

public class Client
{
  Socket sock;
  String server = "XXX.XXX.XX.XX";
  int port = 5550;
  String filename = "/root/log.txt";
  String command = "tail -f "+filename+"\n";

  public static void main(String[] args)
  {
    new Client();
  }

  public Client()
  {
    openSocket();
    try
    {
      // write to socket
      BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
      wr.write(command);
      wr.flush();

      // read from socket
      BufferedReader rd = new BufferedReader(new InputStreamReader(sock.getInputStream()));
      String str;
      while ((str = rd.readLine()) != null)
      {
        System.out.println(str);
      }
      rd.close();
    } 
    catch (IOException e) 
    {
      System.err.println(e);
    }
  }

  private void openSocket()
  {
    // open a socket and connect with a timeout limit
    try
    {
      InetAddress addr = InetAddress.getByName(server);
      SocketAddress sockaddr = new InetSocketAddress(addr, port);
      sock = new Socket();

      // this method will block for the defined number of milliseconds
      int timeout = 2000;
      sock.connect(sockaddr, timeout);
    } 
    catch (UnknownHostException e) 
    {
      e.printStackTrace();
    }
    catch (SocketTimeoutException e) 
    {
      e.printStackTrace();
    }
    catch (IOException e) 
    {
      e.printStackTrace();
    }
  }
}

Server.java

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server  {
    private int portNo = 0;
    private Socket socket = null;

    public Server(int portNo) {
        this.portNo = portNo;
        Thread t = new Thread(new acceptClient());
        t.start();
    }

    class acceptClient implements Runnable {
        public void run() {
            //while(true) {
                try {
                    ServerSocket sSocket = new ServerSocket(portNo);
                    socket = sSocket.accept();
                    System.out.println("A client has connected!");
                    BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

                    BufferedReader rd = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    System.out.println(rd.readLine());
                    rd.close();
                    Process p = null;

                    p = Runtime.getRuntime().exec("tail -f /root/log.txt");
                    BufferedReader rd2 = new BufferedReader(new InputStreamReader(p.getInputStream()));
                    String s = null;
                    while ((s = rd2.readLine()) != null) {
                        System.out.println(s);
                        wr.write(s);
                    }
                    rd2.close();
                    wr.close();
                    /*try {
                            p.waitFor();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }*/

//                  /sSocket.close();
                } catch(IOException exception) {
                    System.out.println("Error: " + exception);
                }
            //}
        }
    }

    public static void main(String[] args) {
        int portNo = 5550;
        new Server(portNo);
    }
}

1 个答案:

答案 0 :(得分:0)

  

我的服务器正在执行命令,但我的客户端没有收到输出。

那是因为,你的命令tail -f是一个永无止境的命令(如果我没错的话)。

  • 因此rd2.readLine()永远不会在null中返回Server.java
  • 这意味着你的while循环永远不会退出。
  • 这意味着,wr.write(s)将继续写入流,但没有获得 有机会flush()close()
  • 因此,输出无法达到 客户。

要修复:只需在flush()下方添加write()

wr.write(s);
wr.flush();
// While loop close.
  

即使我使用了线程

,也只有一个客户端可以连接到服务器

那是因为,您只在Server.java接受一次连接。

仅创建新线程不会接受许多连接。 您需要多次接受它。

我建议您sSocket.accept(),然后在循环中为每个接受的连接创建一个单独的线程。