Android Socket通信--通过jni用c++实现客户端

讲比较重要的代码放到native层是比较好的做法。如果你有需求需要把socket通信的部分封装的jni中实现,那么本文可做参考。

代码思路

1.总共实现三个native方法:

    public native void initSocket(String ip,int port);
    public native void closeSocket();
    public native void sendData(byte[] buffer);

2.initSocket中创建套接字,并连接指定ip和端口的服务器,连接成功后创建线程,由于总是客户端发起请求,因此,当有数据发送给服务断后,唤醒该线程,阻塞读取来自服务端的消息。然后将读到的消息发送到java层,这里只需从native调用java的方法,并把读到的数据传入即可。
3.sendData送来发送数据,它不在本地另开辟线程,需要在java层中开辟线程后调用它向服务器发送请求。
需要注意的点
1.c++中,子线需要首先调用javavm->AttachCurrentThread(&SocketDataDealThread::env,NULL);来获得JNIEnv *的变量,然后使用该变量做进一步操作。
2.c++中跨线程使用JNI创建的变量时,要将其创建为全局引用:

    gObj = env->NewGlobalRef(thiz);
    mSTh = new SocketDataDealThread(socketFd,gObj);

创建工程

android studio2.2版本开始完善了对C/C++ ,请参考开发者文档:向您的项目添加 C 和 C++ 代码。文档是中文的。
本文的工程如图所示:
这里写图片描述
若感兴趣,本文的源码请从这里下载:(免积分的)AndoridJniSocket.zip

本文运行结果展示:
这里写图片描述

操作方式

1.输入Ip和端口号
2.点INIT CLIENT按钮,连接服务器成功后,INIT CLIENT会变成CONNECTED字样,并且按钮无法点击,背景编程深灰色。
3.输入发送内容并点击发送按钮,会看到read:后面出现了你发送的内容。这是因为服务器目前只会将它收到的数据原样返回。
4.点击CLOSE按钮断开连接。

服务器代码

服务器端的代码比较简单,线贴出来:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SockeTest {
   

    public static void main(String[] args) {
        boolean isgo=true;
        int len;
        // TODO Auto-generated method stub
        /**
         * 基于TCP协议的Socket通信,实现用户登录,服务端
        */
        System.out.println("start ...");
        //1、创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
        ServerSocket serverSocket;
        try {
            serverSocket = new ServerSocket(10010);
            //2、调用accept()方法开始监听,等待客户端的连接
            Socket socket = null;
            InputStream is = null;
            InputStreamReader isr = null;
            OutputStream os = null;
            BufferedReader br = null;
            while(isgo){
                System.out.println("start accept");
                socket = serverSocket.accept();
                System.out.println("after accept");
                //3、获取输入流,并读取客户端信息
                is = socket.getInputStream();
                os = socket.getOutputStream();
                isr =new InputStreamReader(is);
                br =new BufferedReader(isr);
                String info =null;
                System.out.println("before read");
                byte[] bbbb = new byte[100];
                while((len = is.read(bbbb))>0){
                    System.out.println(String.valueOf(bbbb));
                    byte[] bbbbb = new byte[len];
                    System.arraycopy(bbbb, 0,bbbbb, 0, len);
                    os.write(bbbbb);
                    os.flush();
                }

                System.out.println("someone connect me");
            }

            //5、关闭资源
            br.close();
            isr.close();
            is.close();
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   

    }

}

客户端

MainActivity.java


import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值