android - Android NDK 套接字连接()在 3g 上失败时返回 0
问题描述
我在 android NDK 中编写了一个套接字,在 c 中编写了一个服务器。它能够很好地连接到服务器。但是,如果服务器关闭或我尝试让它连接到不同的随机 IP,则连接调用仍然返回 0,而它应该返回 -1。
这是客户端的代码:
#include <stdio.h>
#include <jni.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <android/log.h>
#include <unistd.h>
#define APPNAME "MyApp"
#define logcat(...) __android_log_print(ANDROID_LOG_VERBOSE, APPNAME, __VA_ARGS__)
int createSocket() {
int sockFD;
if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
logcat("Unable to create socket");
return -1;
}
logcat("Socket created: %i", sockFD);
return sockFD;
}
JNIEXPORT jint JNICALL
Java_myapp_client( JNIEnv* env,
jobject thiz ) {
struct sockaddr_in server;
int sockFD, new_socket;
char * message;
if ((sockFD = createSocket()) < 0) {
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(server ip);
server.sin_port = htons(8888);
new_socket = connect(sockFD, (struct sockaddr *)&server, sizeof(server));
logcat("Connect return value: %i", new_socket);
int rtn = recv(sockFD, message, sizeof(char), 0);
logcat("Message: %i", rtn);
close(sockFD);
return 1;
}
为套接字创建了一个有效的描述符,当我在服务器不运行的情况下运行它时,connect 和 recv 的返回值为零。可能值得注意的是,android 设备是通过移动互联网连接到互联网的。
解决方案
我删除了 android 特定的部分
#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int createSocket() {
int sockFD;
if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("Unable to create socket");
return -1;
}
printf("Socket created: %i", sockFD);
return sockFD;
}
int main() {
struct sockaddr_in server;
int sockFD, new_socket;
char * message;
if ((sockFD = createSocket()) < 0) {
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(8888);
new_socket = connect(sockFD, (struct sockaddr *)&server, sizeof(server));
printf("Connect return value: %i", new_socket);
int rtn = recv(sockFD, message, sizeof(char), 0);
printf("Message: %i", rtn);
close(sockFD);
return 1;
}
这按预期工作。通过连接到 自行尝试127.0.0.1
。如果您的主机上没有运行服务器,那么它将无法连接(连接将返回 -1 并且将正确设置 errno)。
确保您用于连接的 IP 地址确实指向您的服务器。
recv也有问题:
int rtn = recv(sockFD, message, sizeof(char), 0);
变量message
是一个尚未分配给任何内存的指针(它包含一些堆栈垃圾值)并且您正在覆盖它。参见recv (2) 手册。
要解决此问题,您应该将指针分配给一些分配的内存:
message = malloc(1); //char is always a single byte
或使用堆栈而不是堆来存储消息字节:
char message;
...
int rtn = recv(sockFD, &message, sizeof(char), 0);
我假设你的消息总是一个字节。
请记住,在这里:
printf("Message: %i", rtn);
您正在打印返回代码而不是实际消息。
推荐阅读
- css - Flexbox 项的子项中的溢出问题在 Mac OS 上的 Chrome 中没有滚动条
- pandas - 在 pivot_table 之后对 MultiIndex 列进行排序
- forms - 禁用按钮仍会触发 Click 事件
- c# - .NET 核心 3.1 中的 HttpResponseMessage.Content 出现意外的空行为
- backup - Sanity.io 备份和恢复(或自动保存文档 ID)
- python - 第二个 condor_submit_dag 可以由第一个 DAG 中的节点执行吗?
- javascript - JavaScript 和 MySQL 中多字节字符占用的字符数不同
- ios - Using 5 UIlabels to create 5 stars to mimic a rating system
- javascript - How to continue playing videos when i close an HTML tab?
- sql - 'INSERT' stored procedure with validation