#c #ios #sockets #exc-bad-access
#c #iOS #сокеты #исключение-bad-access
Вопрос:
У меня есть код, который хорошо работает на симуляторе, но как только я пробую его на устройстве, программа выходит из строя.
Это происходит при инициализации сокета.. вот мой код и то, что выдает run / debug. (ИМЯ_СЕРВЕРА — это имя хоста моей машины, на которой запущен сервер)
Ошибка:
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 ( amp;( server_addr.sin_addr ), server->h_addr, server->h_length );
if (connect(connectionSocket, (struct sockaddr *)amp;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 (Продолжайте выполнение) toTarget:self с объектом: nil];
// [NSThread detachNewThreadSelector:@selector (busyLoop) toTarget:self с объектом: nil];
//
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelDidChange) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
// [[NSNotificationCenter defaultCenter] Сервер добавления: self selector:@selector (batteryStateDidChange) имя:UIDeviceBatteryStateDidChangeNotification объект: ноль];
Комментарии:
1. Просто предложение:
server = gethostbyname(SERVER_NAME);
устарело. На getaddrinfo() приятно смотреть2. Каков результат
server = gethostbyname(SERVER_NAME);
Ответ №1:
Попробуйте использовать
memcpy ( amp;( 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**;
Это нормально. Я имею в виду разные протоколы в двух операторах?
Комментарии:
1. @Mayank спасибо за предложение, к сожалению, это, похоже, ничего не изменило.
2. @Michael: Я понимаю, что оба утверждения похожи… Не могли бы вы, пожалуйста, добавить еще немного кода… Например, если вы проверяете значение NULL перед входом внутрь.
3. Однажды я допустил подобную ошибку. В этом случае я проверял
if (NULL == server)
, но сервер был неинициализирован, не установлен в значение NULL. Я надеюсь, что такие вещи уже обрабатываются4. Хм, честно говоря, я возвращаюсь к C после нескольких лет отсутствия, поэтому, возможно, я пропускаю некоторые важные шаги… Я обновил код, чтобы включить всю функцию viewdidload из .m, и я закомментировал все вызовы других локальных функций, чтобы убедиться, что проблема была в этом блоке кода. Когда я сказал, что ваше предложение ничего не изменило, я имел в виду, что программа выполнила то же самое… ваш код не был таким же — я не хотел, чтобы он сработал таким образом.
5. @Michael: Все в порядке. Даже я долгое время не заглядывал в сокеты C. Что ж, нам нужно выяснить, что здесь происходит. Не могли бы вы, пожалуйста, проверить вывод
server = gethostbyname(SERVER_NAME);