如何使用 Socket Programming 连接 Android 设备?

Posted

技术标签:

【中文标题】如何使用 Socket Programming 连接 Android 设备?【英文标题】:How can I connect Android devices using Socket Programming? 【发布时间】:2012-03-12 06:37:23 【问题描述】:

我想创建一个用于连接多个 android 设备的应用程序。这里能够从设备(使用 Wifi 网络)连接到另一个设备(3G 网络)。我需要从使用 3G 网络的设备连接到使用 Wifi 网络的设备。如何我可以将使用 3G 网络的设备连接到 WiFi 网络吗?

Server Side:  

包 com.server.org;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

public class ServerActivity extends Activity 

    private TextView serverStatus;

    // default ip
    public static String SERVERIP = "10.0.2.15";

    // designate a port
    public static final int SERVERPORT = 9191;

    private Handler handler = new Handler();

    private ServerSocket serverSocket;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        serverStatus = (TextView) findViewById(R.id.server_status);

        SERVERIP = getLocalIpAddress();

        Thread fst = new Thread(new ServerThread());
        fst.start();
    

    public class ServerThread implements Runnable 

        public void run() 
            try 
                if (SERVERIP != null) 
                    handler.post(new Runnable() 

                        public void run() 
                            serverStatus.setText("Listening on IP: " + SERVERIP);
                        
                    );
                    serverSocket = new ServerSocket(SERVERPORT);
                    while (true) 
                        // listen for incoming clients
                        Socket client = serverSocket.accept();
                        handler.post(new Runnable() 

                            public void run() 
                                serverStatus.setText("Connected.");

                            
                        );

                        try 
                            BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                            String line = null;
                            while ((line = in.readLine()) != null) 
                                Log.d("ServerActivity", line);
                                handler.post(new Runnable() 

                                    public void run() 
                                        // do whatever you want to the front end
                                        // this is where you can be creative
                                    
                                );
                            
                            break;
                         catch (Exception e) 
                            handler.post(new Runnable() 

                                public void run() 
                                    serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
                                
                            );
                            e.printStackTrace();
                        
                    
                 else 
                    handler.post(new Runnable() 

                        public void run() 
                            serverStatus.setText("Couldn't detect internet connection.");
                        
                    );
                
             catch (Exception e) 
                handler.post(new Runnable() 

                    public void run() 
                        serverStatus.setText("Error");
                    
                );
                e.printStackTrace();
            
        
    

    // gets the ip address of your phone's network
    private String getLocalIpAddress() 
        try 
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) 
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) 
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress())  return inetAddress.getHostAddress().toString(); 
                
            
         catch (SocketException ex) 
            Log.e("ServerActivity", ex.toString());
        
        return null;
    

    @Override
    protected void onStop() 
        super.onStop();
        try 
             // make sure you close the socket upon exiting
             serverSocket.close();
          catch (IOException e) 
             e.printStackTrace();
         
    




Client Side:

包 com.client.org;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class ClientActivity extends Activity 

    private EditText serverIp;

    private Button connectPhones;

    private String serverIpAddress = "";

    private boolean connected = false;

    private Handler handler = new Handler();

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

        serverIp = (EditText) findViewById(R.id.server_ip);
        connectPhones = (Button) findViewById(R.id.connect_phones);
        connectPhones.setOnClickListener(connectListener);
    

    private OnClickListener connectListener = new OnClickListener() 

        @Override
        public void onClick(View v) 
            if (!connected) 
                serverIpAddress = serverIp.getText().toString();
                if (!serverIpAddress.equals("")) 
                    Thread cThread = new Thread(new ClientThread());
                    cThread.start();
                
            
        
    ;

    public class ClientThread implements Runnable 

        public void run() 
            try 
                InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
                Log.d("ClientActivity", "C: Connecting...");
                int SERVERPORT = 9191;
                Socket socket = new Socket(serverAddr,SERVERPORT );
                connected = true;
                while (connected) 
                    try 
                        Log.d("ClientActivity", "C: Sending command.");
                        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
                                    .getOutputStream())), true);
                            // where you issue the commands
                            out.println("Hey Server!");
                            Log.d("ClientActivity", "C: Sent.");
                     catch (Exception e) 
                        Log.e("ClientActivity", "S: Error", e);
                    
                
                socket.close();
                Log.d("ClientActivity", "C: Closed.");
             catch (Exception e) 
                Log.e("ClientActivity", "C: Error", e);
                connected = false;
            
        
    

【问题讨论】:

【参考方案1】:

您的概念有点错误。 3G 连接意味着您的手机必须通过电话网络连接,因此我认为您的手机永远不会有静态 IP。我什至认为今天的运营商不会为电话连接提供静态公共 IP。

我建议您使用网络服务通过网络服务器来桥接这种通信。您可以实施类似APE 的解决方案,并使用两个设备而不是彼此连接到该服务器。

希望对你有帮助

【讨论】:

这里我需要 android 设备之间的点对点连接。我可以使用 WiFi 与设备通信以 3G 连接的设备。但是从 3G 到 WiFi 的连接不起作用。 您是说您能够克服 3G 连接上的动态 IP 问题吗?有的话请分享。回到您的问题,您的情况提示我 WiFi 路由器或路由中的任何其他节点阻塞了传入数据包。检查路由器等中的防火墙以及端口是否被阻止.. 我假设您有 P2P 类型的要求。这就是为什么我建议使用 APE,它是一种实时数据流解决方案。还有其他基于 php 的解决方案更适合且更易于实现。 端口转发方法怎么样?你有什么建议在java中实现这个方法吗? 我总是担心路由器(在 WiFi 上)甚至一些 3G 连接提供商会阻止我的数据包与手机建立连接。您当前的 3G 提供商允许这样做是一件好事,但不是很多,因为他们不希望用户在“无限”连接上使用种子。这就是为什么像 teamviewer 这样的主要应用程序使用静态网络服务器来建立连接的原因。

以上是关于如何使用 Socket Programming 连接 Android 设备?的主要内容,如果未能解决你的问题,请参考以下文章

python learning Network Programming.py

Socket Programming

Socket Programming

Python Socket Programming 服务器/客户端

如何使用 python 连接到 socket.io

如何允许其他网络连接到服务器 nodejs socket io