We have multi platform voip application. For this reason we use basic sockets in C++ (the same implementation for ios, android, linux). One thread reads data from socket and another is used for writing data to socket. Sometimes ios application crash without any crash logs. I localized problem with sockets. if socket is closed on the network or another problem is occured, the function recv return -1. It is ok. But if in the same time another thread call send, application will crash.
I made simple test example:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
static int socketID = -1;
void * ipThread( void *ptr )
{
int bytesRead = 1;
unsigned char pData [1000];
while (bytesRead > 0)
{
bytesRead = (int)recv( socketID, pData, sizeof(pData), 0 );
printf("testNetwork = Data socket: %d\n",bytesRead);
}
{
int bytesSent = (int)send( socketID, pData, 1000, 0 );
printf("testNetwork - Data send to socket: %d\n",bytesSent);
}
shutdown( socketID, SHUT_RDWR );
close( socketID );
socketID = -1;
return NULL;
}
void testNetwork()
{
printf("testNetwork - start\n");
if (socketID != -1)
{
printf("testNetwork - socket exist\n");
unsigned char pData [1000];
int bytesSent = (int)send( socketID, pData, 1000, 0 );
printf("testNetwork - Data send to socket: %d\n",bytesSent);
return;
}
char pIP[] ="yor ip server";
char pPort[] ="5010";
struct addrinfo* ai;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
int err = getaddrinfo(pIP, pPort, &hints, &ai);
if (err != 0)
{
printf("testNetwork - Error getaddrinfo: %d\n",err);
return;
}
socketID = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (socketID <= 0)
{
freeaddrinfo(ai);
printf("testNetwork - Error socket: %d\n",err);
return;
}
int status = connect(socketID, ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(ai);
if (status != 0)
{
socketID = -1;
printf("testNetwork - Error socket: %d\n",err);
return;
}
pthread_t tid; // thread ID
pthread_attr_t attr; // thread attribute
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&tid, &attr, ipThread, NULL);
pthread_attr_destroy(&attr);
}
console output:
testNetwork - start
testNetwork = Data socket: 75
testNetwork = Data socket: -1
and application crashed with call stack in debug window:
Thread 1 Queue : com.apple.main-thread (serial)
#0 0x0000000183fd3de8 in mach_msg_trap ()
#1 0x0000000183fd3c60 in mach_msg ()
#2 0x0000000184516e40 in __CFRunLoopServiceMachPort ()
#3 0x0000000184514908 in __CFRunLoopRun ()
#4 0x0000000184434da8 in CFRunLoopRunSpecific ()
#5 0x000000018641a020 in GSEventRunModal ()
#6 0x000000018e454758 in UIApplicationMain ()
#7 0x000000010053d664 in main
#8 0x0000000183ec5fc0 in start ()
The send function does not exit with current value -1.
the same test on android is corrent. output console is:
testNetwork - start
testNetwork = Data socket: 75
testNetwork = Data socket: -1
testNetwork - Data send to socket: -1
the send funcion return corrent value -1.
Is it possible to set some socket option or something else to get expected result without crash? Thanks.