【问题标题】:Android socket principle and exceptionAndroid socket原理与异常
【发布时间】:2016-08-01 03:44:07
【问题描述】:

我是 android 中的 java 套接字的初学者。我有一些问题,需要帮助来解决它们。

我正在使用底部代码连接到服务器 Socket,一切都很好。但是当调用断开方法并尝试再次连接时,我遇到了socket is null 或 BufferedReader 对象在断开连接并再次连接后总是返回 null 的问题。也许我的断开方式是错误的。在某些时候断开套接字的最佳方法是什么,例如中断互联网并再次连接?

这是我连接和断开套接字的代码。

public class HelperSocket {

public static Socket socket = null;
public static DataOutputStream writer = null;
public static BufferedReader reader = null;
public static DataInputStream inputStream = null;
public static final String SOCKET_ADDRESS = "aUrlForSocket";
public static final int SOCKET_PORT = 6000;
public static final int SOCKET_TIMEOUT = 30000;
public static Thread clientThread;
public static boolean isConnected = false;

public static boolean connect() {
    Utils.Log("StartConnect");
    if (!isConnected) {
        clientThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    InetAddress address = InetAddress.getByName(HelperSocket.SOCKET_ADDRESS);
                     socket = new Socket(address.getHostAddress(), SOCKET_PORT);

                    isConnected = true;
                    socket.setSoTimeout(SOCKET_TIMEOUT);

                    writer = new DataOutputStream(socket.getOutputStream());
                    reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    inputStream = new DataInputStream(socket.getInputStream());

                    while (HelperSocket.isConnected) {
                        Utils.Log("onWhile" + reader.hashCode());
                        try {

                            if (reader.readLine() != null) {
                                Utils.Log(reader.readLine() + "");
                            } else {
                                Utils.Log("getNullFromServer");
                                //data get null here :)
                                disconnect();
                            }
                        } catch (IOException e) {
                            Utils.Log("ProblemOnReadData" + e.getMessage());
                            e.printStackTrace();
                        }
                    }
                } catch (IOException e) {
                    Utils.Log("SocketProblemAt connect:" + e.getMessage());
                    e.printStackTrace();
                }
            }
        });
        clientThread.start();
    }

    return true;
}

public static boolean disconnect() {
    isConnected = false;
    if (!clientThread.isInterrupted())
        clientThread.interrupt();
    if (socket != null) {
        Utils.Log("SocketAndAllObjectCleared");
        try {
            socket.shutdownInput();
            socket.shutdownOutput();
            socket = null;
        } catch (IOException e) {
            e.printStackTrace();
        }

       /* stream = null;
        reader = null;*/
    }
    return false;
}


}

我在网络连接更改中创建了一个接收器,并且需要在设备未连接到互联网时断开套接字并在建立互联网连接时再次连接。

接收者:

public class BroadcastChangeNet extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Utils.isNetworkConnected()) {
            HelperSocket.connect();
            Utils.Log("NetWorkConnect");
        } else {
            HelperSocket.disconnect();
            Utils.Log("NetWorkDisConnect");
        }
    }
}

检查网络情况:

 public static boolean isNetworkConnected() {
        ConnectivityManager conMgr =
                (ConnectivityManager) ApplicationClass.context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo i = conMgr.getActiveNetworkInfo();
        if (i == null)
            return false;
        if (!i.isConnected())
            return false;
        if (!i.isAvailable())
            return false;
        return true;
    }

【问题讨论】:

  • 您需要关闭套接字,而不是关闭它。你正在读一行然后把它扔掉。您需要查看 Java 教程的自定义网络部分。
  • @EJP 如果我关闭套接字,那么我可以重复使用它吗? somwhere read if close socket 可以再次重新打开它。
  • 关闭或者关闭都不能重复使用。你必须创建一个新的。

标签: java android sockets


【解决方案1】:

从我的角度来看,您只需要创建 saprate Jave 类,下面是我测试成功的代码,

import android.content.Context;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

/**
 * Created by Kintan Patel on 01-08-2016.
 */
public class SocketConnection {
    private Socket socket = null;
    private OutputStream outputStream;
    private DataOutputStream dataOutputStream;
    private SessionHelper helper;

    public String EstablishConnection(String token) {
   // token = your message that write on socket server
        String response;
        try {

            //socket = new Socket("192.168.0.24", 2129); // Testing Server
            socket = new Socket("Your IpAddress", PORT NO); 
            outputStream = socket.getOutputStream();
            dataOutputStream = new DataOutputStream(outputStream);
            dataOutputStream.writeUTF(token);
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            response = br.readLine();

        } catch (UnknownHostException e) {
            e.printStackTrace();
            response = "UnknownHostException: " + e.toString();
            return null;

        } catch (SocketException e) {
            e.printStackTrace();
            response = "Sorry Fail to connect";
            return null;

        } catch (IOException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();

            response = "Sorry Fail to connect";
            return null;

        } catch (Exception e) {
            e.printStackTrace();
            response = "Server Break";
            return null;

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

现在从您的主类中简单地创建 SocketConnection 类的对象并使用EstablishConnection() 方法,

eg :

     SocketConnection connection = new SocketConnection();
         String token = "message that you want to write on server";
         String response = connecation.EstablishConnection(token);

如果你想使用 AsynkTask,下面是 AsynkTask 代码:

private class ActivationTask extends AsyncTask<String, String, String> {

        @Override
        protected String doInBackground(String... params) {
            SocketConnection connection = new SocketConnection();
            String token = "getActivation|" + params[0] + "|";
            return connection.EstablishConnection(token);
        }


        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog.show();
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            progressDialog.dismiss();
            if (s != null) {
                 Log.e("RESULT" , s);



            }
        }
    }

【讨论】:

  • 感谢@kintanpatel。只是一个小问题:如果我关闭套接字,我可以重新打开并再次使用吗?
  • 是的,您可以重新打开它。
猜你喜欢
  • 2013-06-30
  • 1970-01-01
  • 2012-08-12
  • 1970-01-01
  • 2022-12-22
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多