1

我正在尝试在链接上编译代码。

该代码不起作用,因为它被挂断在这一行:

textIn.setText(dataInputStream.readUTF());

出于某种原因,它没有挂断,writeUTF()但它被挂断了readUTF()

谁能在这里指出我正确的方向?

这是我的代码:

public Socket socket = null;
public DataOutputStream dataOutputStream = null;
public DataInputStream dataInputStream = null;
public Thread readjsonthrd = new Thread(new ReadJSONThread());

private final static String LOG_TAG = AndroidClient.class.getSimpleName();
private final Handler handler = new Handler();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Log.e(LOG_TAG, "Before OnCreate() Try");
    try {
        Log.e(LOG_TAG, "In OnCreate() Try");
        socket = new Socket("23.23.175.213", 9000);
        Log.e(LOG_TAG, "Created Socket");
        dataOutputStream = new DataOutputStream(socket.getOutputStream());
        Log.e(LOG_TAG, "Created DataOutputStream");
        dataInputStream = new DataInputStream(socket.getInputStream());
        Log.e(LOG_TAG, "Created DataInputStream");

        Profile p = new Profile();
        Log.e(LOG_TAG, "Created Profile Instance");

        //Gets the local profile via JSON and converts into Profile type
        Gson gson = new Gson();
        Log.e(LOG_TAG, "Created Gson Instance");
        p = gson.fromJson(p.getProfileJSONStr(), Profile.class);
        Log.e(LOG_TAG, "Converted Profile to JSON");

        //Gson gson = new Gson();
        Log.e(LOG_TAG, "Before: outputJSON = gson.toJson(p);");
        outputJSON = gson.toJson(p);
        Log.e(LOG_TAG, "Created outputJSON");

        dataOutputStream.writeUTF(outputJSON); //OUTPUT OF JSON FROM LOCAL PROFILE BEING SENT TO THE SERVER
        dataOutputStream.flush();
        Log.e(LOG_TAG, "Created dataOutputStream");
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Log.e(LOG_TAG, "Before initEventHandlers");
    initEventHandlers();
    Log.e(LOG_TAG, "Create Thread");
    Thread serverthrd = new Thread(new ServerThread());

    Log.e(LOG_TAG, "Start Thread");
    serverthrd.start();
    Log.e(LOG_TAG, "Started Thread");
}

public class ServerThread implements Runnable { 
    @Override
    public void run() {
        // TODO Auto-generated method stub
    //Socket socket = null;
    //DataOutputStream dataOutputStream = null;
    //DataInputStream dataInputStream = null;
        Log.e(LOG_TAG, "Before Server Try Statement");
    try {
        Log.e(LOG_TAG, "In Server Try Statement");
        //socket = new Socket("23.23.175.213", 1337);

        //dataOutputStream = new DataOutputStream(socket.getOutputStream());
        //dataInputStream = new DataInputStream(socket.getInputStream());
        /*Profile p = null;

        //Gets the local profile via JSON and converts into Profile type
        Gson gson = new Gson();
        p = gson.fromJson(p.getProfileJSONStr(), Profile.class);

        //Gson gson = new Gson();
        outputJSON = gson.toJson(p);
        dataOutputStream.writeUTF(outputJSON); //OUTPUT OF JSON FROM LOCAL PROFILE BEING SENT TO THE SERVER
        */
        //dataOutputStream.writeUTF(textOut.getText().toString());  //OUTPUT JSON GOES HERE
        //textIn.setText(dataInputStream.readUTF());


        Log.e(LOG_TAG, "Start Thread");
        readjsonthrd.start();
        Log.e(LOG_TAG, "Started Thread");
        /*Log.e(LOG_TAG, "Before inputJSON String");
        inputJSON = dataInputStream.readUTF();

        //Convert 
        Log.e(LOG_TAG, "After inputJSON String");
        Log.e(LOG_TAG, "InputJSON:" + inputJSON);*/

        //textIn.setText(dataInputStream.readUTF());  //GET JSON COMING FROM SERVER HERE
        refreshViewModels();
    } /*catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }*/
    finally{
        if (socket != null){
            try {
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (dataOutputStream != null){
            try {
                dataOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (dataInputStream != null){
            try {
                dataInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }


    }
}

public class ReadJSONThread implements Runnable { 
    @Override
    public void run() {
        // TODO Auto-generated method stub
    //Socket socket = null;
    //DataOutputStream dataOutputStream = null;
    //DataInputStream dataInputStream = null;
        Log.e(LOG_TAG, "Before Read JSON Try Statement");
        try {
            Log.e(LOG_TAG, "Before inputJSON String");
            inputJSON = dataInputStream.readUTF();

            //Convert 
            Log.e(LOG_TAG, "After inputJSON String");
        }
        catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
4

5 回答 5

5

我在与一个 gov API 集成时遇到了一些类似的问题,我使用的是 readUTF() writeUTF(),并且每次都停留在 readUTF() 没有任何响应。

我发现服务器在 c 中,并且期望以 * 结尾或请求字符串,响应也以 * 结尾

我通过直接写入套接字的输入/输出流来解决这个问题,并在遇到**时终止读取。

        Socket client = new Socket(serverIp, port);
        OutputStream out = client.getOutputStream();
        InputStream in = client.getInputStream();

        String test = "REQUEST-STRING**";
        out.write(test.getBytes());
        out.flush();

        int c;
        while ((c=in.read())!=-1) {
            if (isEndOfResponse(c)) {
                break;
            }
            System.out.print((char)c);
        }
        client.close();
于 2013-04-27T14:46:31.030 回答
1

readUTF()是阻塞网络调用。Thread您应该从不是主 UI的单独调用它Thread,这就是该示例的操作方式。因为它是阻塞的,所以它会挂起当前的Thread直到接收到数据,因此为什么你应该给它一个单独的。

Android 文档实际上特别推荐这样做,因为您将收到“应用程序未响应”错误,因为网络调用等待时间过长。

编辑:根据您提供的代码,您只是设置Thread错误。您想在 Thread 本身中创建 Socket(或者您可以通过构造函数传递它)。仅使用中的readUTF()方法Thread不会有太大作用。

我的建议是在类中创建一些名为write()and的包装器方法,然后在其中实现相应的方法。然后在你的方法中创建你的对象,当你想写的时候你可以调用. 对于阅读,我会在该方法中创建一个循环,当它成功从网络中读取数据时,让它从您的 Activity 类中调用一个方法来执行数据处理。read()ReadJSONThreadSocketonCreate()Thread<thread>.write()read()

于 2012-08-07T06:29:54.243 回答
1

代替

读取UTF()

如果你

读取线()

你应该摆脱你的问题(假设你的服务器发送了一两行正确终止的行作为答案)。

注意:如果您在主活动中运行它,从 ICS 开始,您将遇到限制在主线程中打开网络连接的问题。如果您选择不禁用限制,一种快速的解决方案是 asynctask,它可能不允许您访问主布局(和 textview)。

于 2013-01-10T00:11:08.313 回答
0

readUTF()是特定于 java 的:首先它读取两个字节并将其用作长度,然后读取字节并将它们视为修改后的 UTF-8。基本上,要使其工作,您需要一个使用writeUTF().

此外,您不应在 UI 线程上运行长时间运行的操作(= 网络调用)。这将阻止 UI 重绘和事件处理,因此您的应用程序将显示为“挂起”。使用AsyncTask在后台线程上运行长时间运行的任务。

于 2012-08-07T06:36:57.983 回答
0

您可以使用线程:

  public  static DataInputStream dis;
//...
    Thread thread = new Thread() {
                @Override
                public void run() {

                   while (Connected) {
                       String msg = null;
                       try {
                           if(dis==null)break;
                           msg = dis.readLine();
                           Log.i("TAG", "dataRecived: "+msg);
                       } catch (IOException e) {
                           e.printStackTrace();
                       }

                    }
                    Log.i("TAG", "Reciver END");
                }
            };

            thread.start();

所以你的应用程序在使用 readLine 或 readUTF 时不会挂起

于 2019-06-21T08:32:45.257 回答