前言
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 __cplusplus
extern "C" {
#endif
static 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:发送成功");
}