【问题标题】:C Socket crash on iPhone device. EXC_BAD_ACCESSiPhone 设备上的 C Socket 崩溃。 EXC_BAD_ACCESS
【发布时间】:2011-08-29 08:25:58
【问题描述】:

我的代码在模拟器上运行良好,但我一在设备上尝试,程序就会崩溃。

初始化套接字时会发生这种情况。这是我的代码和运行/调试吐出的内容。 (SERVER_NAME 是我运行服务器的机器的主机名)

错误:

Program received signal:  “EXC_BAD_ACCESS”.
warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.3 (8J3)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).

在.h中

    int connectionSocket;
struct hostent *server;
struct sockaddr_in server_addr;

在.m

- (void)viewDidLoad {
[super viewDidLoad];

TRANSFER_COMPLETED = false;
TIME_COMPLETED = false;

//[UIApplication sharedApplication].idleTimerDisabled = YES;    //Disable app sleep (check this out)


//Build connection to Server
portNumber = PORT_NUM;
connectionSocket = socket(PF_INET, SOCK_STREAM, 0); 
server = gethostbyname(SERVER_NAME);
server_addr.sin_family = AF_INET;     
server_addr.sin_port = htons(portNumber);   
//server_addr.sin_addr = *((struct in_addr *)server->h_addr);   
memcpy ( &( server_addr.sin_addr ), server->h_addr, server->h_length );

if (connect(connectionSocket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) 
{
    perror("Connect");
    exit(1);
}   

//Setup Battery monitoring and Device characteristics
myDevice = [UIDevice currentDevice];
myDevice.batteryMonitoringEnabled = YES;
NSString* sysName = myDevice.systemName;
NSString* sysVersion = myDevice.systemVersion;

//Name the file for this device

NSString* myString = [NSString stringWithFormat:@"systemName:%@ systemVersion:%@ \n", sysName, sysVersion];

const char* deviceInfo = malloc(128);
char* deviceSettings = malloc(256);

deviceInfo = [myString UTF8String];

//Get the battery State
int intBatteryState = myDevice.batteryState;
char* batteryState = malloc(24);
switch(intBatteryState){
    case 0: 
        batteryState = "Unknown";
        break;
    case 1:
        batteryState = "Unplugged";
        break;
    case 2:
        batteryState = "Charging";
        break;
    case 3:
        batteryState = "plugged and full";
        break;
    default:
        batteryState = "Error";
        break;
}   

sprintf(deviceSettings, "iOS Test *** APPLICATION_BUFFER_SIZE(B): %i, SLEEP_TIME(microseconds) per app buffer size: %i, TOTAL_BYTES_EXPECTED per download: %i, TOTAL_DOWNLOADS: %i, TEST_TIME(s): %i, Battery State:%s \n", (int) round(APPLICAION_BUFFER_SIZE), SLEEP_TIME, TOTAL_BYTES_EXPECTED, TOTAL_DOWNLOADS, TEST_TIME, batteryState);

send(connectionSocket, DEVICE_NAME, strlen(DEVICE_NAME), 0);
sleep(1);
send(connectionSocket, deviceSettings, strlen(deviceSettings), 0);
send(connectionSocket, deviceInfo, strlen(deviceInfo), 0);

free(deviceSettings);
//free(deviceInfo);//Says it is being freed without being allocated but I allocated it with malloc...
//free(batteryState); 

//  [NSThread detachNewThreadSelector:@selector(download) toTarget:self withObject:nil];

// [NSThread detachNewThreadSelector:@selector(keepRunning) toTarget:self withObject:nil]; // [NSThread detachNewThreadSelector:@selector(busyLoop) toTarget:self withObject:nil]; //

//  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelDidChange) name:UIDeviceBatteryLevelDidChangeNotification object:nil];

// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStateDidChange) name:UIDeviceBatteryStateDidChangeNotification object:nil];

【问题讨论】:

  • 只是一个建议:server = gethostbyname(SERVER_NAME); 已弃用。很高兴看到getaddrinfo()
  • server = gethostbyname(SERVER_NAME); 的输出是什么

标签: c ios sockets exc-bad-access


【解决方案1】:

尝试使用

memcpy ( &( serv_addr.sin_addr ), server->h_addr, server->h_length );

代替

server_addr.sin_addr = *((struct in_addr *)server->h_addr);  

或者你可以使用server_addr.sin_addr.s_addr = inet_addr(IP);

这只是为了避免崩溃。但我不确定为什么server_addr.sin_addr = *((struct in_addr *)server->h_addr); 会崩溃。

编辑: 试试这个:

portNumber = PORT_NUM;
connectionSocket = socket(AF_INET, SOCK_STREAM, 0); 
server_addr.sin_family = AF_INET;     
server_addr.sin_port = htons(portNumber);   
server_addr.sin_addr.saddr = htonl(INADDR_ANY);

这不需要server = gethostbyname(SERVER_NAME);

我注意到的另一件事是:

connectionSocket = socket(**PF_INET**, SOCK_STREAM, 0); 
//server = gethostbyname(SERVER_NAME);
server_addr.sin_family = **AF_INET**;  

这样好吗。我的意思是两个语句中的不同协议?

【讨论】:

  • @Mayank 感谢您的建议,不幸的是它似乎没有任何改变。
  • @Michael:我知道这两个语句是相似的...您能否添加更多代码...就像您在进入之前检查 NULL 一样。
  • 我曾经犯过类似的错误。在那种情况下,我正在检查 if (NULL == server) 但服务器未初始化,未设置为 NULL。我希望这些事情已经在处理中了
  • 嗯,老实说,几年后我正在重新研究 C,所以我可能会遗漏一些重要的步骤......我已经更新了代码以包含来自 .m 的整个 viewdidload 函数和我注释掉了对其他本地函数的所有调用,以确保问题出在该代码块中。当我说你的建议没有改变任何东西时,我的意思是程序执行相同......不是你的代码是相同的 - 我不是故意让它以这种方式脱落。
  • @Michael:没关系。即使我很长一段时间都没有研究 C 套接字。好吧,我们需要弄清楚这里发生了什么。你能检查一下server = gethostbyname(SERVER_NAME);的输出吗?
猜你喜欢
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多