如何在Android中创建Socket连接?

我有一个应用程序,我需要创建套接字连接。 我的要求是,一旦我的套接字连接建立,它需要活着,直到我亲自关闭它。 每隔3分钟,我必须将数据包发送到另一端。 任何人都可以提供一些代码示例,这有助于我这样做吗?

Solutions Collecting From Web of "如何在Android中创建Socket连接?"

Android中的套接字连接与Java中的相同: http : //www.oracle.com/technetwork/java/socket-140484.html

你需要注意的事情:

  1. 如果手机进入睡眠状态,您的应用将不再执行,因此套接字最终会超时。 你可以通过唤醒锁来防止这种情况。 这将极大地耗尽设备电池 – 我知道我不会使用该应用程序。
  2. 如果您经常这样做,即使您的应用程序未处于活动状态,您也需要使用服务。
  3. 操作系统可以随时杀死活动和服务,特别是如果它们是非活动应用程序的一部分。

如果您需要计划执行代码,请查看AlarmManager

即使用户不再使用该应用程序(即应用程序处于非活动状态),您是否需要运行代码并接收数据?

在这篇文章中,您将find在设备之间或同一移动设备中的两个应用程序之间建立套接字的详细代码。

您必须创建两个应用程序来测试下面的代码。

在两个应用程序的清单文件中 ,添加以下权限

  

第一个应用代码:客户端套接字

activity_main.xml中

 < ?xml version="1.0" encoding="utf-8"?>          

MainActivity.java

 import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; /** * Created by Girish Bhalerao on 5/4/2017. */ public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView mTextViewReplyFromServer; private EditText mEditTextSendMessage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button buttonSend = (Button) findViewById(R.id.btn_send); mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message); mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server); buttonSend.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_send: sendMessage(mEditTextSendMessage.getText().toString()); break; } } private void sendMessage(final String msg) { final Handler handler = new Handler(); Thread thread = new Thread(new Runnable() { @Override public void run() { try { //Replace below IP with the IP of that device in which server socket open. //If you change port then change the port number in the server side code also. Socket s = new Socket("xxx.xxx.xxx.xxx", 9002); OutputStream out = s.getOutputStream(); PrintWriter output = new PrintWriter(out); output.println(msg); output.flush(); BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream())); final String st = input.readLine(); handler.post(new Runnable() { @Override public void run() { String s = mTextViewReplyFromServer.getText().toString(); if (st.trim().length() != 0) mTextViewReplyFromServer.setText(s + "\nFrom Server : " + st); } }); output.close(); out.close(); s.close(); } catch (IOException e) { e.printStackTrace(); } } }); thread.start(); } } 

第二个应用代码 – 服务器套接字

activity_main.xml中

 < ?xml version="1.0" encoding="utf-8"?>        

MainActivity.java

 import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * Created by Girish Bhalerao on 5/4/2017. */ public class MainActivity extends AppCompatActivity implements View.OnClickListener { final Handler handler = new Handler(); private Button buttonStartReceiving; private Button buttonStopReceiving; private TextView textViewDataFromClient; private boolean end = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonStartReceiving = (Button) findViewById(R.id.btn_start_receiving); buttonStopReceiving = (Button) findViewById(R.id.btn_stop_receiving); textViewDataFromClient = (TextView) findViewById(R.id.tv_data_from_client); buttonStartReceiving.setOnClickListener(this); buttonStopReceiving.setOnClickListener(this); } private void startServerSocket() { Thread thread = new Thread(new Runnable() { private String stringData = null; @Override public void run() { try { ServerSocket ss = new ServerSocket(9002); while (!end) { //Server is waiting for client here, if needed Socket s = ss.accept(); BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter output = new PrintWriter(s.getOutputStream()); stringData = input.readLine(); output.println("FROM SERVER - " + stringData.toUpperCase()); output.flush(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } updateUI(stringData); if (stringData.equalsIgnoreCase("STOP")) { end = true; output.close(); s.close(); break; } output.close(); s.close(); } ss.close(); } catch (IOException e) { e.printStackTrace(); } } }); thread.start(); } private void updateUI(final String stringData) { handler.post(new Runnable() { @Override public void run() { String s = textViewDataFromClient.getText().toString(); if (stringData.trim().length() != 0) textViewDataFromClient.setText(s + "\n" + "From Client : " + stringData); } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_start_receiving: startServerSocket(); buttonStartReceiving.setEnabled(false); buttonStopReceiving.setEnabled(true); break; case R.id.btn_stop_receiving: //stopping server socket logic you can add yourself buttonStartReceiving.setEnabled(true); buttonStopReceiving.setEnabled(false); break; } } } 

简单socket服务器应用示例

我已经发布了一个客户端示例: https : //stackoverflow.com/a/35971718/895245 ,所以这里是一个服务器示例。

此示例应用程序运行一个服务器,该服务器返回输入的ROT-1密码。

然后你需要添加一个Exit按钮+一些睡眠延迟,但这应该让你开始。

要玩它:

  • 安装应用程序
  • 在局域网上安装手机和PC
  • 通过https://android.stackexchange.com/a/130468/126934find您手机的IP
  • 运行netcat $PHONE_IP 12345
  • 键入一些行

Android套接字与Java相同,但我们必须处理一些权限问题。

SRC / COM / cirosantilli / android_cheat /sockets

我们需要一个Service或其他后台方法或者: 如何修复android.os.NetworkOnMainThreadException?

 package com.cirosantilli.android_cheat.socket; import android.app.Activity; import android.app.IntentService; import android.content.Intent; import android.os.Bundle; import android.util.Log; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; public class Main extends Activity { static final String TAG = "AndroidCheatSocket"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(Main.TAG, "onCreate"); Main.this.startService(new Intent(Main.this, MyService.class)); } public static class MyService extends IntentService { public MyService() { super("MyService"); } @Override protected void onHandleIntent(Intent intent) { Log.d(Main.TAG, "onHandleIntent"); final int port = 12345; ServerSocket listener = null; try { listener = new ServerSocket(port); Log.d(Main.TAG, String.format("listening on port = %d", port)); while (true) { Log.d(Main.TAG, "waiting for client"); Socket socket = listener.accept(); Log.d(Main.TAG, String.format("client connected from: %s", socket.getRemoteSocketAddress().toString())); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintStream out = new PrintStream(socket.getOutputStream()); for (String inputLine; (inputLine = in.readLine()) != null;) { Log.d(Main.TAG, "received"); Log.d(Main.TAG, inputLine); StringBuilder outputStringBuilder = new StringBuilder(""); char inputLineChars[] = inputLine.toCharArray(); for (char c : inputLineChars) outputStringBuilder.append(Character.toChars(c + 1)); out.println(outputStringBuilder); } } } catch(IOException e) { Log.d(Main.TAG, e.toString()); } } } } 

AndroidManifest.xml中

必须添加: 否则: Java套接字IOException – 权限被拒绝

 < ?xml version="1.0" encoding="utf-8"?>              

在带有build.xml GitHub上: https : //github.com/cirosantilli/android-cheat/tree/92de020d0b708549a444ebd9f881de7b240b3fbc/socket