【问题标题】:Application Hangs over the socket, Unable to read client data at server side应用程序挂在套接字上,无法在服务器端读取客户端数据
【发布时间】:2015-09-26 17:47:59
【问题描述】:

我正在尝试实现客户端服务器套接字连接,在该连接中我通过 GUI 传递 ls/pwd 之类的命令,并使用 url(localhost) 在端口建立服务器连接。虽然我能够与客户端建立连接,但代码不会超出客户端连接接受状态。 IE。它不会读取客户端通过套接字发送的服务器端输入。下面是我的三个类,Mainserver、ClientHandler(处理服务器的线程连接)和Client。

这是客户端操作按钮执行的代码:

   private void jButton1ActionPerformed(java.awt.event.ActionEventevt)      {                                         

            command = jTextField1.getText();
            String url = jTextField3.getText();
            try {
                System.out.println("Before socket connection");
                Socket socket = new Socket(url, 9002);
                System.out.println("After socket connection");
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                System.out.println("After Buffered readers");
                System.out.println("After getting streams");

                if (socket != null) {
                    try {
                        int x = Integer.parseInt(command);
                        flag = 1;
                    } catch (Exception e) {
                        flag = 0;
                    }
                    if (flag == 0) {
                        String[] cmd = {"/bin/sh", "-c", command};

                        System.out.println("the value of command in GUI class is " + Arrays.toString(cmd));
                        try {

                            String commd = Arrays.toString(cmd);
                            System.out.println(commd);

                            out.write(commd);
                            input = in.readLine();
                        }
                        catch (IOException ex1)
                                {
                            Logger.getLogger(TestGUI.class.getName()).log(Level.SEVERE, null, ex1);
                                    }

                        jTextField2.setText(input.toString());

                    }
                }

            }//try end of the first one
            catch (IOException ex) {
                Logger.getLogger(TestGUI.class.getName()).log(Level.SEVERE, null, ex);
            }

服务器类:

public class ServerMain {



    public static void main(String[] args) throws IOException, InterruptedException {

        int number, temp;
        try {

            ServerSocket serverSocket = new ServerSocket(9002);
            System.out.println("server has been started in the server");
            System.out.println("Server is waiting connection at" + InetAddress.getLocalHost().getCanonicalHostName() + "port" + serverSocket.getLocalPort());

            while (true) {
                Socket socket = serverSocket.accept();

                System.out.println("Client Connection Accepted");

                //pass on handling on this client to a thread
                (new ClientHandler(socket)).start();

            }
        } catch (Exception e) {
            System.err.println("Server already in use");
            System.exit(-1);
        }
    }
}

服务器的客户端处理程序:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author ameerah
 */
public class ClientHandler extends Thread {

    private static int BUFSIZE = 1024;

    private StringBuffer result;
    ServerSocket serverSocket;
    String serverText;
    StringBuffer output = new StringBuffer();
    private Object serversocket;

    public Socket getSock() {
        return sock;
    }

    public void setSock(Socket sock) {
        this.sock = sock;
    }

    Socket sock;

    public ClientHandler(Socket sock) {
        this.sock = sock;
    }

    @Override
    public void run() {
        PrintWriter outWriter = null;
        try {
            BufferedReader myInput = new BufferedReader(new InputStreamReader(sock.getInputStream()));
            outWriter = new PrintWriter(sock.getOutputStream());
            System.out.println(
                    "before accepting the command in server");
            String inputLine;
            while ((inputLine = myInput.readLine()) != null) //String command = myInput.readLine();
            {
                System.out.println(inputLine);

                String result = "";
                try {
                    result = executeCommand(inputLine);
                } catch (IOException ex) {
                    Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InterruptedException ex) {
                    Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
                }
                System.out.println(result);
                outWriter.write(result);
            }
        } catch (IOException ex) {
            Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            outWriter.close();
        }
    }

    public String executeCommand(String cmd)
            throws IOException, InterruptedException {
        try {

            Process p = Runtime.getRuntime().exec(cmd);
            p.waitFor();
            BufferedReader reader
                    = new BufferedReader(new InputStreamReader(p.getInputStream()));
            System.out.println("Inside the execute method");
            String line = "";
            while ((line = reader.readLine()) != null) {

                output.append(line + "\n");
            }

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

        return output.toString();

    }

}

我已经有一段时间了,并尝试使用不同的流,例如 ObjectInputStream、ObjectOutputStream,但代码每次都挂起。我现在看不到我哪里出错了:(我已经在几个论坛中搜索过,但我仍然不知道我在这里哪里出错了。不胜感激。! 最好的问候

【问题讨论】:

  • 你试过的命令值是多少?
  • 代码太多。你能提取最小的例子吗?
  • 也许是个愚蠢的问题,但示例命令是什么?如果您的命令是整数,您将不会进入 (flag == 0) 分支。你是否已经到了确定通过套接字发送然后你的客户端挂起的地步?
  • 它还不是完整的代码,只是尝试构建它,没有套接字它运行良好。我暂时正在尝试使用命令,例如 ls/pwd。我可以看到客户端连接被接受,但是我认为来自客户端的输入没有到达服务器,因此它正在等待输入并挂起。

标签: java ios multithreading sockets


【解决方案1】:

最后是 readLine() 期待 '\n'。因此,一旦我在末尾附加了 '\n' 并添加了 out.flush() 它就能够读取并且不会一直挂起等待更多输入,现在应用程序正在运行。 非常感谢您的有益建议。 out.flush() 建议被证明非常有用。

【讨论】:

    【解决方案2】:

    隔离问题的一些技巧。

    1. 检查 command 的值并捕获异常堆栈跟踪。

    2. out.write(commd);之后:再添加一行out.flush();刷新之后,服务器将从客户端获取数据。 outWriter 也是如此。写入数据后,应在 outWriter 上调用 flush()

    【讨论】:

    • 命令的值是多少?这对于理解问题很重要。你有什么例外吗?你知道卡住的地方吗?
    【解决方案3】:

    您正在寻找行尾来结束输入循环,但您正在使用 write。

    将您的发送数据语句更改为使用 println。

    客户:

        out.println(commd);
    

    服务器:

         outWriter.println(result);
    

    【讨论】:

      猜你喜欢
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 2014-08-31
      • 1970-01-01
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      相关资源
      最近更新 更多