NDK 开发之 Socket 编程

来源:互联网 发布:图灵出版社 java 编辑:程序博客网 时间:2024/06/06 06:53

前言

socket 作为开发人员必须掌握的一个技能,今天我在Android中使用到了.并且写出了一个小例子,本片文章作为一个记录

Tcp连接

实现流程盗用一张图:
这里写图片描述
流程中名称都是每一个步骤需要调用的函数名称

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>#include <stdlib.h>#include <stdio.h>#include <android/log.h>#include <sys/socket.h>#include <sys/types.h>#include <sys/un.h>#include <netinet/in.h>#include <stddef.h>#include <arpa/inet.h>#include <unistd.h>/* Header for class com_move_ndk1_NativeClass1 */#ifndef _Included_com_move_ndk1_NativeClass1#define _Included_com_move_ndk1_NativeClass1#ifdef __cplusplusextern "C" {#endifstatic int serverSocket;static int clientSocket;/* * Class:     com_move_ndk1_NativeClass1 * Method:    test * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_move_ndksocket_MainAct_server        (JNIEnv *env, jclass jc) {    int tcpSocket = socket(PF_INET, SOCK_STREAM, 0);    if (tcpSocket == -1) {        return (*env)->NewStringUTF(env, "socket失败");    }    struct sockaddr_in address;    memset(&address, 0, sizeof(address));    address.sin_family = PF_INET;    address.sin_addr.s_addr = htonl(INADDR_ANY);    address.sin_port = htons(12345);    int bindState = bind(tcpSocket, (struct sockaddr_in *) &address, sizeof(address));    if (bindState == -1) {        return (*env)->NewStringUTF(env, "bind失败");    }    int listenState = listen(tcpSocket, 1);    if (listenState == -1) {        return (*env)->NewStringUTF(env, "listen失败");    }    struct sockaddr_in accept_address;    socklen_t addressLength = sizeof(address);    int acceptState = accept(tcpSocket, &accept_address, &addressLength);    if (acceptState == -1) {        return (*env)->NewStringUTF(env, "accept失败");    }    __android_log_print(ANDROID_LOG_ERROR, "accept", "accept");    serverSocket = acceptState;    char arr[10];    int recvSize = recv(serverSocket, arr, 10, 0);    if (recvSize <= 0) {        return (*env)->NewStringUTF(env, "recv失败");    }    int lastOne = arr[recvSize - 1];    __android_log_print(ANDROID_LOG_ERROR, "socket", "lastOne = %d\n", lastOne);    __android_log_print(ANDROID_LOG_ERROR, "socket", "recvSize = %d\n", recvSize);    return (*env)->NewStringUTF(env, arr);}JNIEXPORT jstring JNICALL Java_com_move_ndksocket_MainAct_client        (JNIEnv *env, jclass jc) {    int tcpSocket = socket(PF_INET, SOCK_STREAM, 0);    if (tcpSocket == -1) {        return (*env)->NewStringUTF(env, "socket失败");    }    struct sockaddr_in address;    memset(&address, 0, sizeof(address));    address.sin_family = PF_INET;    int inet_atonSstate = inet_aton("127.0.0.1", &address.sin_addr.s_addr);    if (inet_atonSstate == -1) {        return (*env)->NewStringUTF(env, "inet_aton失败");    }    address.sin_port = htons(12345);    int connectState = connect(tcpSocket, &address, sizeof(address));    if (connectState == -1) {        return (*env)->NewStringUTF(env, "connect失败");    }    clientSocket = tcpSocket;    return (*env)->NewStringUTF(env, "成功");}JNIEXPORT jint JNICALL Java_com_move_ndksocket_MainAct_send        (JNIEnv *env, jclass jc) {    char charData[] = "hello";    send(clientSocket, charData, sizeof(charData) / sizeof(char), 0);    close(clientSocket);    return sizeof(charData) / sizeof(char);}#ifdef __cplusplus}#endif#endif

上述写了三个方法,第一个方法监听了12345端口等待客户端连接,accept方法用于阻塞并且等待用户连接,第二个方法用于连接,并且第一个方法中接受连接,第三个方法发送了一定的数据,第一个方法的recv阻塞方法中获取到数据

Udp连接

JNIEXPORT jstring JNICALL Java_com_move_ndksocket_MainAct_udpServer        (JNIEnv *env, jclass jc) {    int udpSocket = socket(PF_INET, SOCK_DGRAM, 0);    if (udpSocket == -1) {        return (*env)->NewStringUTF(env, "udp:socket失败");    }    __android_log_print(ANDROID_LOG_ERROR, "socket", "udpSocket\n");    struct sockaddr_in address;    memset(&address, 0, sizeof(address));    address.sin_family = PF_INET;    address.sin_addr.s_addr = htonl(INADDR_ANY);    address.sin_port = htons(12346);    int bindState = bind(udpSocket, &address, sizeof(address));    if (bindState == -1) {        return (*env)->NewStringUTF(env, "bind失败");    }    char cc[100];    struct sockaddr_in recvfromAddress;    memset(&recvfromAddress, 0, sizeof(recvfromAddress));    socklen_t l = sizeof(struct sockaddr_in);    ssize_t recvSize = recvfrom(udpSocket, cc, 8, 0, &recvfromAddress, &l);    __android_log_print(ANDROID_LOG_ERROR, "socket", "recvSize\n");    if (recvSize == -1) {        return (*env)->NewStringUTF(env, "udp接受失败");    }    return (*env)->NewStringUTF(env, cc);}JNIEXPORT jstring JNICALL Java_com_move_ndksocket_MainAct_udpSend        (JNIEnv *env, jclass jc) {    int udpSocket = socket(PF_INET, SOCK_DGRAM, 0);    if (udpSocket == -1) {        return (*env)->NewStringUTF(env, "udp:socket失败");    }    struct sockaddr_in address;    memset(&address, 0, sizeof(address));    inet_aton("127.0.0.1", &(address.sin_addr));    address.sin_port = htons(12346);    sendto(udpSocket, "udpHello", 9, 0, &address, sizeof(address));    return (*env)->NewStringUTF(env, "udp:发送成功");}

源码在我的github上存放着,有需要的可以下载一下

ndkSocket下载