Android的NDK的UDPsocket通信

本文介绍了一个简单的UDP客户端和服务端实现案例,包括C语言源代码及构建配置。客户端发送消息到服务端,并接收服务端反馈,实现了基本的双向通信功能。

客户端:

microphone.c文件:

#include <netinet/in.h>   
#include <sys/types.h> 
#include <sys/socket.h>   
#include <unistd.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <jni.h>

#include <android/log.h>
static const char *TAG="uart";
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)

int main()
{
const char tos[10] = "123456789";
int sock;
//sendto中使用的对方地址
struct sockaddr_in toAddr;
//在recvfrom中使用的对方主机地址
struct sockaddr_in fromAddr;
unsigned int fromLen;
char recvBuffer[128];
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sock < 0){
LOGD("__________________socket fail.\r\n");
exit(1);
}
LOGD("___________________socket success.\r\n");
memset(&toAddr,0,sizeof(toAddr));
toAddr.sin_family=AF_INET;
toAddr.sin_addr.s_addr=inet_addr("10.0.2.11");//服务端IP
toAddr.sin_port = htons(4000);
if(sendto(sock,tos,strlen(tos),0,(struct sockaddr*)&toAddr,sizeof(toAddr)) != strlen(tos)){
LOGD("___________________sendto() fail.\r\n");
close(sock);
exit(1);
}
LOGD("___________________sendto() succes.\r\n");
fromLen = sizeof(fromAddr);
if(recvfrom(sock,recvBuffer,128,0,(struct sockaddr*)&fromAddr,&fromLen)<0){
LOGD("___________________recvfrom()fail.\r\n");
close(sock);
exit(1);
}
LOGD("___________________recvfrom()success.\r\n");
LOGD("___________________recvfrom() result:%s\r\n",recvBuffer);
close(sock);
}

JNINativeMethod gMethods[] = {
{"main", "()V", (void *)main},
};

const char *classPathName = "com/starnet/microphone/Microphone";
jint JNI_OnLoad(JavaVM* vm, void* reserved){
JNIEnv* env;
jclass clazz;

if((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK){
return JNI_ERR;
}

clazz = (*env)->FindClass(env, classPathName);
(*env)->RegisterNatives(env, clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0]));

return JNI_VERSION_1_4;
}

Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := microphone
LOCAL_SRC_FILES := microphone.c
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

服务端:

player.c文件:

#include <netinet/in.h>   
#include <sys/types.h>   
#include <sys/socket.h>    
#include <unistd.h>   
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <jni.h>

#include <android/log.h>
static const char *TAG="uart";
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)

int main()
{
int sock;
//sendto中使用的对方地址
struct sockaddr_in toAddr;
//在recvfrom中使用的对方主机地址
struct sockaddr_in fromAddr;
int recvLen;
unsigned int addrLen;
char recvBuffer[128];
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sock < 0)
{
LOGD("_____________socket fail.\r\n");
exit(0);
}
LOGD("______________socket success.\r\n");
memset(&fromAddr,0,sizeof(fromAddr));
fromAddr.sin_family=AF_INET;
fromAddr.sin_addr.s_addr=htonl(INADDR_ANY);
fromAddr.sin_port = htons(4000);
if(bind(sock,(struct sockaddr*)&fromAddr,sizeof(fromAddr))<0)
{
LOGD("____________bind() fail.\r\n");
close(sock);
exit(1);
}
while(1){
addrLen = sizeof(toAddr);
if((recvLen = recvfrom(sock,recvBuffer,128,0,(struct sockaddr*)&toAddr,&addrLen))<0){
LOGD("________________recvfrom() fail..\r\n");
close(sock);
exit(1);
}
LOGD("___________________recvfrom() result:%s\r\n",recvBuffer);
if(sendto(sock,recvBuffer,recvLen,0,(struct sockaddr*)&toAddr,sizeof(toAddr))!=recvLen){
LOGD("________________sendto fail\r\n");
close(sock);
exit(0);
}
LOGD("________________sendto success\r\n");
return 0;
}
}

JNINativeMethod gMethods[] = {
{"main", "()V", (void *)main},
};

const char *classPathName = "com/starnet/player/Player";
jint JNI_OnLoad(JavaVM* vm, void* reserved){
JNIEnv* env;
jclass clazz;
if((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK){
return JNI_ERR;
}

clazz = (*env)->FindClass(env, classPathName);
(*env)->RegisterNatives(env, clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0]));
return JNI_VERSION_1_4;
}

Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := player
LOCAL_SRC_FILES := player.c
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

java文件直接调用main即可。且需要先开启服务端,然后才开启客户端。OK

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值