Android作为SocketServer以及手机IP问题

本文探讨了将Android设备作为Socket服务器时遇到的问题,尤其是公网环境下内网IP的不可达性。作者通过实例说明在WiFi环境中可以实现手机与后台的Socket连接,但在公网中由于运营商动态分配的内网IP,导致无法直接访问。解决方案可能是使用第三方推送平台或改为手机主动拉取消息。
摘要由CSDN通过智能技术生成

一、前言:为了公司研究推送和保活方案

尝试了以Android作为Socket长连接的服务端server,以后台作为Socket的客户端client,后台进行推送,这样的目的是保证,后台不需要长时间连接多个设备,后台每次有新的消息,创建多个Client通过Socket推送给Android终端设备,数据传输完成后,所有的client终端关闭,释放资源。而Android作为SocketServer一直监听端口,处于挂起状态,所以保证了推送数据的实时性。当然这种做法缺点很明显:1.Android长期挂起耗电,2.一旦Android终端程序被杀,无法推送到手机,3.Android应用层没有真正的保活,4.也是最大的问题Android终端能通过3G、4G上网,WIFI上网,VPN翻墙上网,作为SocketServer需要提供公网的IP,因此Android端的IP是多少?怎么获取?

二、开发过程:

2.1、带着以上问题,进行Demo的编写和测试

2.2 开发环境:Android 5.1设备,后台Springboot集成的Tomcat服务

2.3 具体代码:

后台代码

 

 

@RequestMapping("/efss/test")
@RestController
public class TestController extends BaseController {


    @RequestMapping("/uploadTerminalIp")
    public ApiResponse<Object> uploadTerminalIp(@RequestBody String json) {
        JSONObject jsonObject = JSONObject.parseObject(json);
        JSONObject jsonData = jsonObject.getJSONObject("nameValuePairs");
        String ip = jsonData.getString("ip");
        Integer port = jsonData.getInteger("port");
        if (StringUtils.isBlank(ip)) {
            return apiFail("ip地址为空");
        }
        if (null == port) {
            return apiFail("port为空");
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        String currentTimeStr = TimeUtil.getDate2String(new Date(), "yyyy-MM-dd HH:mm:ss") + ",随机码:" + new Random().nextFloat();
                        String responseStr = SocketUtil.tcpPost(ip, port.toString(), currentTimeStr);
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        }).start();

        return apiSuccess("Socket connected....!!!.............");
    }

}

模拟后台接口中直接写了一个定时,每5秒通过Socket向Android发送一个时间。

贴下SocketUtil 只负责写(推送消息),不读,当然如果需要自己添加实现

/**
 * * Created by jambestwick@126.com
 * * on 2019/5/31
 * *
 */
public class SocketUtil {
    private static final Logger logger = LoggerFactory.getLogger(SocketUtil.class);

    /**
     * 发送socket请求
     *
     * @param clientIp
     * @param clientPort
     * @param msg
     * @return
     */
    public static synchronized String tcpPost(String clientIp, String clientPort, String msg) {
        String rs = "";

        if (clientIp == null || "".equals(clientIp) || clientPort == null || "".equals(clientPort)) {
            logger.error("Ip或端口不存在...");
            return null;
        }

        int clientPortInt = Integer.parseInt(clientPort);

        logger.info("clientIp:" + clientIp + " clientPort:" + clientPort);

        Socket s = null;
        OutputStream out = null;
        //InputStream in = null;
        try {
            s = new Socket(clientIp, clientPortInt);
            s.setSendBufferSize(4096);
            s.setTcpNoDelay(true);
            s.setSoTimeout(60 * 1000);
            s.setKeepAlive(true);
            out = s.getOutputStream();
            //in = s.getI
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值