我已经在 android 的本机部分(即在 C 中)实现了一个 UDP 客户端。为了从服务器(PC)接收数据,我的设备和 PC 都通过 wifi 连接。
当客户端安装在有根设备上时,它能够完美地接收来自服务器的数据。然而,在非根设备上,虽然它没有显示任何错误,但它无法发送/接收数据表单/到服务器。
下面是我的服务器代码:
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
int main()
{
int cont,create_socket,new_socket,addrlen,fd;
int bufsize = 3000;
int nameLen=0;
int client_address_size=0;
char *buffer = malloc(bufsize);
char fname[256];
struct sockaddr_in address,client;
if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) > 0)
printf("The socket was created\n");
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(15000);
if (bind(create_socket,(struct sockaddr *)&address,sizeof(address))== 0)
printf("Binding Socket\n");
nameLen=sizeof(address);
if (getsockname(create_socket,(struct sockaddr *)&address,&nameLen)<0)
{
printf("\n\ngetsockname() error\n");
exit(3);
}
printf("Port assigned is %d\n", ntohs(address.sin_port));
client_address_size=sizeof(client);
if(recvfrom(create_socket,fname, 255,0,(struct sockaddr *) &client,&client_address_size)<0)
{
printf("\n\nrecvfrom() failed\n");
exit(4);
}
printf("A request for filename %s Received..\n", fname);
if ((fd=open(fname, O_RDONLY))<0)
{
perror("File Open Failed");
exit(0);
}
while((cont=read(fd, buffer, bufsize))>0)
{
sleep(1);
sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,client_address_size);
printf("\n\nPacket sent\n");
}
sendto(create_socket,"*",1,0,(struct sockaddr *) &client,client_address_size);
printf("Request Completed\n");
return close(create_socket);
}
android NDK 上的客户端代码:
JNIEXPORT void JNICALL Java_com_examplemyPlayer_startClient
(JNIEnv *env, jclass jobj, jint portNo, jstring argv1)
{
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","start client has entered....",NULL);
//int portno=portNo;
const char *servIP = (*env)->GetStringUTFChars(env, argv1, 0);
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","Server IP address:%s",servIP);
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","Server Port No.:%d",portno);
qBuff=(unsigned char *)malloc(sizeof(char)*Q_SIZE);//qBuff is a global pointer
int create_socket,cont;
int bytesWritten=0;
int bufsize = 3000;
int server_address_size=0;
char *buffer = malloc(bufsize);
char reqFname[8]="Bub.bin";
struct sockaddr_in address,server;
int serv_addr_size = sizeof(address);
if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) < 0)
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","The Socket was NOT created",NULL);
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","The Socket was successfully created",NULL);
address.sin_family = AF_INET;
address.sin_port = htons(15000);
address.sin_addr.s_addr=inet_addr(servIP);
if((sendto(create_socket, reqFname, sizeof(reqFname), 0,(struct sockaddr *) &address,sizeof(address)))==-1)
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","Error sending filename to server",NULL);
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","Request Accepted... \n\nReceiving File...",NULL);
server_address_size=sizeof(server);
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","Contents of the file are:",NULL);
while((cont=recvfrom(create_socket, buffer, bufsize, 0,(struct sockaddr *) &address,&serv_addr_size))>0)
{
if(buffer[cont-1]=='*')
break;
memcpy(qBuff+r,buffer,cont);//copying received data to a circular queue
r=(r+3000)%Q_SIZE;
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","Bytes received:%d",cont);
//write(1, buffer, cont);
}
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","EOF",NULL);
free(qBuff);
close(create_socket);
}
上面的代码适用于有根设备,但不适用于无根设备。由于我正在创建的应用程序应该能够在有根设备和无根设备上运行,因此我还需要使代码在无根设备上运行。
只有在使用/sbin/services iptable stop禁用 Linux 防火墙后,服务器才能连接到 root 设备。那么是否有用于阻止通信端口的无根设备的防火墙。在上面的代码中,我正在尝试端口号 15000。但是我也尝试过其他端口,但没有锻炼。
因此,我恳请读者提供有用的答案或参考链接。提前致谢。