简体   繁体   English

应用程序挂在套接字上,无法在服务器端读取客户端数据

[英]Application Hangs over the socket, Unable to read client data at server side

I am trying to implement a client server socket connection where i am passing commands like ls/pwd over the GUI and I use an url(localhost) to establish the server connection at the port. 我正在尝试实现客户端服务器套接字连接,其中我通过GUI传递ls / pwd之类的命令,并且我使用url(localhost)在端口处建立服务器连接。 Although i am able to establish a connection with client ,the code does not proceed beyond the Client Connection accepted state. 尽管我能够与客户端建立连接,但是代码不会超出“客户端连接”接受状态。 Ie it does not read the input at the server end which was sent by the client over the socket. 也就是说,它不会读取客户端通过套接字发送的服务器端输入。 Below are my three classes, Mainserver, ClientHandler(this handles the thread connections for the server)and the Client. 下面是我的三个类,Mainserver,ClientHandler(用于处理服务器的线程连接)和Client。

This is the Client Action button performed code: 这是客户端操作按钮执行的代码:

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

The server class: 服务器类:

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

The client Handler for the Server: 服务器的客户端处理程序:

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

    }

}

I have been at it for some time, and tried using different streams such as ObjectInputStream, ObjectOutputStream, but the code hangs each time. 我已经使用了一段时间,并尝试使用不同的流,例如ObjectInputStream,ObjectOutputStream,但是代码每次都挂起。 I cannot see at this point where Im going wrong :( I've searched in several forums but I do not still get an idea where Im going wrong here.Would appreciate any help.! Best Regards 在这一点上,我看不到我哪里出错了:(我在几个论坛中进行了搜索,但是我仍然不知道我这里哪里出错了。不胜感激。

It was the readLine() which was expecting '\\n' at the end. 是readLine()在结尾处期望“ \\ n”。 Therefore once i appended '\\n' at the end and added out.flush() it was able to read and not keep hanging waiting for more inputs, and now the application is working. 因此,一旦我在末尾附加了'\\ n'并添加了out.flush(),它便能够读取并且不再挂起等待更多的输入,现在该应用程序正在运行。 Thank you very much for your helpful suggestions. 非常感谢您的有益建议。 The out.flush() advice proved to be very helpful. 实践证明out.flush()建议非常有用。

Few tips to isolate the problem. 一些提示,以找出问题所在。

  1. Check the value of command and catch Exception stack trace. 检查命令的值并捕获异常堆栈跟踪。

  2. After out.write(commd); out.write(commd); : add one more line out.flush(); :再增加一行out.flush(); After flush, server will get the data from client. 刷新后,服务器将从客户端获取数据。 Same is the case with outWriter. outWriter也是如此。 flush() should be called on outWriter after writing the data. 写入数据后,应在outWriter上调用flush()

You are looking for an end of line to end your input loop but you are using write. 您正在寻找要结束输入循环的行尾,但您正在使用写操作。

Change your send data statements to use println. 更改您的发送数据语句以使用println。

Client: 客户:

    out.println(commd);

Server: 服务器:

     outWriter.println(result);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM