【问题标题】:Android Java Socket Socket TCPIP open connectionAndroid Java Socket Socket TCPIP 打开连接
【发布时间】:2010-12-29 23:45:54
【问题描述】:

我需要通过 TCPIP 连接到服务器。我发现了如何做到这一点,但这些例子并没有建立永久连接,它只是连接发送数据并断开连接。我需要保持连接打开以来回传递几个包。

例如,我习惯于请求连接,然后有一个进程来监听传入的数据。像这样:

  1. 连接
  2. 确认连接
  3. 发送数据
  4. 接收数据...返回#3
  5. 关闭连接。

关于这个或更好的示例代码我能读到什么吗?

【问题讨论】:

    标签: java android sockets tcp


    【解决方案1】:

    从现在 (ICS+) 开始,要建立网络连接,您将需要使用 AsyncTask(或处理程序),除非您愿意移除限制(不建议!)。默认情况下,网络连接受限于主活动线程。

    这个 AsyncTask 可以解决问题(另一方面,我有一个 c++ 套接字服务器)。在这种情况下,我打开套接字,发送我从主要活动收到的字符串,接收答案,发送另一条消息(这次是“你好”)并在关闭连接之前接收最终消息。

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import android.os.AsyncTask;
    import android.util.Log;
    
    public class SocketConnect extends AsyncTask <String, Integer, String> {
    
        String TAG = "TGsocket";
    
        @Override
        protected String doInBackground(String... params) {
            String url = params[0];
            String textSend = params[1];
            Log.i(TAG, "textsend = |" + textSend + "|");
            Socket socket = null;
            DataOutputStream dataOutputStream = null;
            DataInputStream dataInputStream = null;
            try {
                socket = new Socket(url, 9090);
                dataOutputStream = new DataOutputStream(socket.getOutputStream());
                dataInputStream = new DataInputStream(socket.getInputStream());
                Log.i(TAG,"socket OK");
                dataOutputStream.writeUTF(textSend);
                String textInNow = dataInputStream.readLine();
                Log.w(TAG, "says Server = " + textInNow);
                dataOutputStream.writeUTF("hello there");
                textInNow = dataInputStream.readLine();
                Log.w(TAG, "says 2ndTime Server = " + textInNow);
            } catch (UnknownHostException e) {
                Log.e(TAG, "at thread unknownHost " + e.getMessage());
                e.printStackTrace();
            } catch (IOException e) {
                Log.e(TAG, "at thread IO " + e.getMessage());
                e.printStackTrace();
            }
    
            finally{
                Log.i(TAG, "finally");
                if (dataOutputStream != null){
                    try {
                        dataOutputStream.close();
                    } catch (IOException e) {
                        Log.e(TAG, "at thread dataoutput IO " + e.getMessage());
                        e.printStackTrace();
                    }
                }
    
                if (dataInputStream != null){
                    try {
                        dataInputStream.close();
                    } catch (IOException e) {
                        Log.e(TAG, "at thread datainput IO " + e.getMessage());
                        e.printStackTrace();
                    }
                }
                if (socket != null){
                    try {
                        Log.i(TAG, "socket closed");
                        socket.close();
                    } catch (IOException e) {
                        Log.e(TAG, "at thread finally IO " + e.getMessage());
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }
           @Override
           protected void onPreExecute() {
              super.onPreExecute();
              //displayProgressBar("Downloading...");
           }
        @Override
           protected void onProgressUpdate(Integer... values) {
              super.onProgressUpdate(values);
              //updateProgressBar(values[0]);
           }
    
           @Override
           protected void onPostExecute(String result) {
              super.onPostExecute(result);
           }
    }
    

    调用使用(在try catch中):

    SocketConnect("100.100.100.100","some string");
    

    其中“100.100.100.100”是您服务器的 IP。

    注意1:不要忘记设置互联网使用权限(在您的清单文件中) 注意 2:您可以安全地删除 Log 调用和大多数检查,以及 3 个最终覆盖(我只是将其全部留在那里,因为它在某些情况下更容易构建)。

    在 froyo、姜饼、ics 和 jb 上测试。

    【讨论】:

      【解决方案2】:

      我做了一个类似的应用程序,但用途不同,只是服务器端没有监听,只有发送。但是,它确实在循环中保持打开状态,您可以将其修改为,在接收到特定消息后,在 while 循环中使用 strstr 命令关闭循环和连接。代码见这个话题:Garbage data transmitted in WiFi TCP connection from desktop to Android,换行:

      n = write(newsockfd, string, sizeof(string));
      

      n = write(newsockfd, string, strlen(string));
      

      为了解决我遇到的问题。

      【讨论】:

      • 如果没有更多流量,我想我可以设置一个计时器,在一段时间后停止后台。
      【解决方案3】:

      也许您还是应该选择更高级别的库,例如“Apache MINA”或“Netty”?

      【讨论】:

      • 我找到了 MINA,但没有简单的例子可以扩展 TCPIP 客户端。到目前为止,我还没有在 Netty 上找到很多东西
      • 终于找到了Netty,没有找对方法。我只需要一个简单的问候,好的,再见了连接上的几个步骤,所以我想我会坚持使用低级别的东西。谢谢!