Android - 服务器套接字

Posted

技术标签:

【中文标题】Android - 服务器套接字【英文标题】:Android - Server Socket 【发布时间】:2011-11-19 06:43:09 【问题描述】:

我对 android 中的 Socket 通信有一些疑问。

1)我已经为 android 开发了监听 8888 端口的服务器套接字应用程序。

a) 当我在模拟器上托管我的服务器时,我无法通过我电脑上的客户端应用程序与它通信,因为(模拟器和客户端)应用程序都在我的笔记本电脑上并且在同一个网络上,我认为他们应该能够相互交流。

b) 当我在我的 android 移动设备上部署相同的服务器应用程序并尝试通过我在我的 PC 上的相同客户端应用程序进行通信时,客户端应用程序会出现超时异常,因为它无法与之通信。

我的第一个问题是如何使用 Emulator 和 1 个 android 设备测试服务器/客户端套接字应用程序?我什至可以使用我的 PC 的客户端套接字应用程序来测试我的服务器套接字吗?

**我的其他应用程序有客户端套接字应用程序,因此客户端应用程序没有问题。

2) 我的第二个问题是在 android 设备上测试我的服务器应用程序,我必须转发所需的端口吗? a) 对于模拟器:如何转发端口? b)对于设备:我如何转发端口? c) 我可以通过编程方式转发端口吗?

**仅供参考:

我正在使用 Eclipse 作为 android 开发工具。

** 我的服务器代码,因为我的服务器套接字代码也可能有问题。

Socket socket = null;
            DataInputStream dataInputStream = null;
            DataOutputStream dataOutputStream = null;
            ServerSocket serverSocket = null;
        try
          
            serverSocket = new ServerSocket(SERVERPORT);
            System.out.println("Listening :" + SERVERPORT);
            System.out.println("Server IP:" + SERVERIP);
        
        catch (Exception e) 
                       
            e.printStackTrace();
        
        while(true)
        
            try
            
                socket = serverSocket.accept();
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                System.out.println("ip: " + socket.getInetAddress());                   
                String str = in.readLine();
                System.out.println("message Received: " + str);
             
            catch (Exception e) 
                               
                e.printStackTrace();
                           
            finally
            
                if( socket!= null)
                
                    try 
                    
                        socket.close();
                    
                    catch (IOException e) 
                    
                        e.printStackTrace();
                    
                
                if( dataInputStream!= null)
                
                    try
                    
                        dataInputStream.close();
                    
                    catch (IOException e) 
                    
                        e.printStackTrace();
                    
                                   
                if( dataOutputStream!= null)
                
                    try 
                    
                        dataOutputStream.close();
                    
                    catch (IOException e) 
                    
                        e.printStackTrace();
                    
                
            
        

已编辑: 一个非常有趣的部分是,如果我将端口设置为 8080 PC 的客户端套接字应用程序确实连接到我的 android 设备上的 Android 应用程序,但我没有在我的服务器上收到套接字,也没有收到我发送的数据。链接后没有任何反应 => socket = serversocket.accept();

我还在清单中设置了权限。

【问题讨论】:

【参考方案1】:

感谢问题和答案。它帮助我找出通向我的工作组合的狭窄路径。

这个过程比我们预期的要复杂。套接字客户端必须使用“127.0.0.1”而不是“192.168.0.15”或“10.0.2.15”来连接到同一台计算机上的 Android 模拟器。以下是我尝试并有效的 6 个步骤。

步骤 0:转到终端

第 1 步:使用 adb、Android Debug Bridge 找出 Android 模拟器控制台的端口(在我的情况下端口是 5554) /Users/zhijunsheng/Library/Android/sdk/platform-tools/adb devices 附加设备列表 9357cefb 装置 emulator-5554 设备

第二步:获取安卓模拟器控制台的auth_token cat /Users//.emulator_console_auth_token sncfmfC+Lg9OtAT4

第 3 步:连接到 Android 模拟器控制台 远程登录本地主机 5554 正在尝试 ::1... 连接到本地主机。 好的

第 4 步:验证 认证 sncfmfC+Lg9OtAT4

第五步:添加重定向指令 重新添加 tcp:50000:50001

我也有 a video in YouTube 记录我的尝试。

【讨论】:

【参考方案2】:

关于如何从模拟器访问网络的第一个问题:模拟器在其自己的网络地址空间上运行,与您的 PC 隔离。您必须配置网络重定向才能访问网络上的设备。

在https://developer.android.com/studio/run/emulator-networking.html查看更多详情

【讨论】:

好吧,这对我有用,现在剩下的唯一问题是如何在我的 android 设备上运行同一台服务器? 不确定我是否遵循了这个问题。你的意思是你上面的场景1b?如果是这样,它应该可以正常工作,假设 PC 正在尝试通过暴露给网络的端口(配置为转发的端口)进行连接。 是的,唯一没有回答的问题是关于安卓设备的。当我在 Emulator 上转发端口时,它可以与 PC 的 Socket 设备通信,但我确实知道如何使该 PC 的客户端应用程序与部署在 android 设备上的 Android 应用程序通信。 确保您在客户端应用程序上使用重定向端口。除此之外,没有什么大秘密。您还可以尝试另外两件事:1) 完全在 PC 上测试您的客户端/服务器应用程序(在 PC 上运行 Java 代码,而不是在 Android 上)以确保它不是与 Android 无关的编码问题和 2) 运行 Wireshark ( google 和下载)查看连接失败的确切位置(例如,客户端应用程序发送 TCP SYN,但没有收到 ACK,或者甚至没有来自应用程序的 SYN)。 @Seth:修复链接,指向新页面。谢谢你让我知道。我了解链接的风险。但是,它们周围的说明和细微差别并不是那么简单。我必须在这里复制整个页面以使其有用。在这种情况下,链接必须做。【参考方案3】:

您是否在 Manifest.xml 中设置了正确的权限?

<uses-permission android:name="android.permission.INTERNET" />

需要设置套接字

【讨论】:

以上是关于Android - 服务器套接字的主要内容,如果未能解决你的问题,请参考以下文章

示例:使用AsyncTask的Android双向网络套接字

Android,错误套接字异常 (SOCKS)

Android 中的 ActionScript 套接字

Android 套接字连接组合发送

使用 Android 应用程序、服务、套接字 + 谷歌地图 API - 啥是正确的方法?

如何通过 Kotlin 在 Android 中使用套接字