How to set up a UNIX domain socket in iOS? - ios

I am trying to set up a UNIX domain socket in iOS. According to https://iphonedevwiki.net/index.php/Unix_sockets, this is the code that I used to set up the socket on the server side:
const char *socket_path = "/var/run/myserver.socket";
// setup socket
struct sockaddr_un local;
strcpy(local.sun_path, socket_path);
unlink(local.sun_path);
local.sun_family = AF_UNIX;
int listenfd = socket(AF_UNIX, SOCK_STREAM, 0);
printf("listenfd: %d\n", listenfd);
// start the server
int r = -1;
while(r != 0) {
r = bind(listenfd, (struct sockaddr*)&local, sizeof(local));
printf("bind: %d\n", r);
usleep(200 * 1000);
}
int one = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
// start listening for new connections
r = -1;
while(r != 0) {
r = listen(listenfd, 20);
printf("listen: %d\n", r);
usleep(200 * 1000);
}
// wait for new connection, and then process it
int connfd = -1;
while(true) {
if(connfd == -1) {
// wait for new connection
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
printf("new connfd: %d\n", connfd);
}
// process incoming data
char buffer[4096];
int len = recv(connfd, buffer, sizeof(buffer), 0);
if(len == 0) {
printf("connfd %d disconnected!\n", connfd);
connfd = -1;
continue;
} else {
printf("connfd %d recieved data: %s", connfd, buffer);
// send some data back (optional)
const char *response = "got it!\n";
send(connfd, response, strlen(response) + 1, 0);
}
}
However, when I run this code on my iPhone, I got this in the console:
listenfd: 3
bind: -1
bind: -1
bind: -1
bind: -1
bind: -1
...
It looks like there is a problem when we do bind() as it returns -1, I want to know what I am doing wrong in the code?
The errno is 1, which is OPERATION_NOT_PERMITTED

You are not allowed to create objects in /var/run on iOS. You need to put the socket in a directory where you are allowed to create objects, like FileManager.shared.temporaryDirectory.

Related

LWIP threads seems to block any other threads on my FREERTOS setup on a arty Z7

I am learning freertos and lwip on a Arty Z7.
I have managed to launch several tasks without problem but when I try to setup a lwip server to receive TCP packets, the server works perfectly but the other tasks won't continue their work.
So when I run the following code, the xil_printf of the "dumb_task" is writing correctly its message until the PHY autonegation is complete. Then, Nothing will happen from the dumb_task but the connection from the tcp port are accepted by the fpga. (I have commented by purpose the receive packet thread as it's changing nothing).
Do you have any ideas of what could be the problem?
Thank you!
Here is my code:
what is in my main file:
static sys_thread_t g_server_th_handle;
void dumb_task(void *p){
while(1){
xil_printf("dummy!\n");
vTaskDelay(10);
}
}
int main()
{
xTaskCreate (dumb_task, "TestTask", 512, NULL, 4, NULL);
g_server_th_handle = create_server_thread(2);
vTaskStartScheduler();
while(1);
return 0;
}
what is in a .cpp/.h file for the server:
static sys_thread_t g_server_thread_handle;
static int complete_nw_thread;
struct netif server_netif;
int g_server_tasks_priority = DEFAULT_THREAD_PRIO;
void setting_thread(void *p)
{
/* the mac address of the board. this should be unique per board */
u8_t mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
/* Add network interface to the netif_list, and set it as default */
if (!xemac_add(&server_netif, NULL, NULL, NULL, mac_ethernet_address,
PLATFORM_EMAC_BASEADDR)) {
xil_printf("Error adding N/W interface\r\n");
return;
}
netif_set_default(&server_netif);
/* specify that the network if is up */
netif_set_up(&server_netif);
/* start packet receive thread - required for lwIP operation */
sys_thread_new("xemacif_input_thread",
(void(*)(void*))xemacif_input_thread, &server_netif,
THREAD_STACKSIZE, g_server_tasks_priority);
complete_nw_thread = 1;
vTaskResume(g_server_thread_handle);
vTaskDelete(NULL);
}
void accept_loop()
{
int sock, new_sd;
int opt=1;
struct sockaddr_in address, remote;
int size;
// set up address to connect to
memset(&address, 0, sizeof(address));
if ((sock = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
xil_printf("TCP server: Error creating Socket\r\n");
return;
}
address.sin_family = AF_INET;
address.sin_port = htons(TCP_CONN_PORT);
address.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0) {
xil_printf("TCP server: Unable to bind to port %d\r\n",
TCP_CONN_PORT);
close(sock);
return;
}
ioctl(sock,FIONBIO,&opt);
if (listen(sock, 0) < 0) {
xil_printf("TCP server: tcp_listen failed\r\n");
close(sock);
return;
}
size = sizeof(remote);
xil_printf("Server set and listening\n\r");
for(;;) {
if ((new_sd = accept(sock, (struct sockaddr *)&remote,
(socklen_t *)&size)) > 0){
char *ip = inet_ntoa(((struct sockaddr_in*) &remote)->sin_addr);
gTCP_connection_count +=1;
xil_printf("New connection from %s. Number of client : %d\n\r",
ip,gTCP_connection_count);
/*sys_thread_new("TCP_recv thread",
tcp_recv_traffic, (void*)&new_sd,
TCP_SERVER_THREAD_STACKSIZE,
g_server_tasks_priority);*/
}
vTaskDelay(pdMS_TO_TICKS( 1UL ));
}
}
void server_thread(void *p)
{
// /* initialize lwIP before calling sys_thread_new */
lwip_init();
/* any thread using lwIP should be created using sys_thread_new */
sys_thread_new("nw_thread", setting_thread, NULL,
THREAD_STACKSIZE, g_server_tasks_priority);
/* Suspend Task until auto-negotiation is completed */
if (!complete_nw_thread){
vTaskSuspend(NULL);
}
assign_default_ip(&(server_netif.ip_addr), &(server_netif.netmask),
&(server_netif.gw));
print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask),
&(server_netif.gw));
/* start the application*/
accept_loop();
vTaskDelete(NULL);
return;
}
sys_thread_t create_server_thread(int priority){
g_server_tasks_priority = priority;
g_server_thread_handle = sys_thread_new("server_thread", server_thread, 0,
THREAD_STACKSIZE, priority );
return g_server_thread_handle;
}

Pthread semaphore TCP

I wanna create 2 threads in client, each thread will send a message to server and get rebounce or download a file from server, using TCP protocole. This program run very well when I didn't add pthread in it. After I created 2 threads in client, It doesn't communicate with server. Normally, thread will tell server which operation it wants, then server respond, but when one thread send the message, there is no respond from server, and this thread exit immediately, next thread occupy the semaphore but exit without chose the operation.
Code
void semaphore()
{
int nThread = 2;
int nSemaphore = 1;
int nRet = -1;
pthread_t threadIDs[nThread];
nRet = sem_init(&sem, 0, nSemaphore);
if(nRet == -1)
{
perror("Semaphore intialization failed!!!\n");
exit(EXIT_FAILURE);
}
int i;
for (i = 0; i < nThread; ++i)
{
nRet = pthread_create(&threadIDs[i], NULL, thread, NULL);
if(nRet != 0)
{
perror("pthreas_create failed!!!\n");
exit(EXIT_FAILURE);
}
}
for(i = 0; i < nThread; ++i)
{
nRet = pthread_join(threadIDs[i], NULL);
if(nRet != 0)
{
printf("Threan %d join failed!!!\n", i);
exit(EXIT_FAILURE);
}
}
sem_destroy(&sem);
}
enter code here
void *thread(void* p)
{
pthread_t id = pthread_self();
sem_wait(&sem);
pthread_mutex_lock(&mutex);
int operation ;
//向服务器(特定的IP和端口)发起请求
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址
serv_addr.sin_port = htons(1234); //端口
printf("\nThis is client %ld", id);
printf("\nWhich operation do you want:\n");
printf("1:Sending message to server and get rebound\n");
printf("2:Downlown a file from server\n");
scanf("Your chose:%d", &operation);
switch(operation)
{
case 1:
{
sendMessage(serv_addr);
break;
}
case 2:
{
download(serv_addr);
break;
}
default:
break;
}
sem_post(&sem);
pthread_mutex_unlock(&mutex);
}
From terminal
This is client 139671599236864
Which operation do you want:
1:Sending message to server and get rebound
2:Downlown a file from server
Your choise:1
This is client 139671590844160
Which operation do you want:
1:Sending message to server and get rebound
2:Downlown a file from server
Can someone tell me where is the problem?

Socket with IOS cocos2dx

I need to build an game use Socket to connect multi device.
I have a problem when i try to create socket on cocos2dx.
void AcceptCallBack(
CFSocketRef socket,
CFSocketCallBackType type,
CFDataRef address,
const void *data,
void *info)
{
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFIndex bytes;
UInt8 buffer[128];
UInt8 recv_len = 0, send_len = 0;
/* The native socket, used for various operations */
CFSocketNativeHandle sock = *(CFSocketNativeHandle *) data;
/* The punch line we stored in the socket context */
char *punchline = info;
/* Create the read and write streams for the socket */
CFStreamCreatePairWithSocket(kCFAllocatorDefault, sock,
&readStream, &writeStream);
if (!readStream || !writeStream) {
close(sock);
fprintf(stderr, "CFStreamCreatePairWithSocket() failed\n");
return;
}
CFReadStreamOpen(readStream);
CFWriteStreamOpen(writeStream);
/* Wait for the client to finish sending the joke; wait for newline */
memset(buffer, 0, sizeof(buffer));
while (!strchr((char *) buffer, '\n') && recv_len < sizeof(buffer)) {
bytes = CFReadStreamRead(readStream, buffer + recv_len,
sizeof(buffer) - recv_len);
if (bytes < 0) {
// fprintf(stderr, "CFReadStreamRead() failed: %d\n", bytes);
close(sock);
return;
}
// NSLog(#"Read: %d", bytesRead);
NSLog(#"buffer: %s", buffer);
recv_len += bytes;
}
/* Send the punchline */
while (send_len < (strlen(punchline+1))) {
if (CFWriteStreamCanAcceptBytes(writeStream)) {
bytes = CFWriteStreamWrite(writeStream,
(unsigned char *) punchline + send_len,
(strlen((punchline)+1) - send_len) );
if (bytes < 0) {
fprintf(stderr, "CFWriteStreamWrite() failed\n");
close(sock);
return;
}
send_len += bytes;
}
close(sock);
CFReadStreamClose(readStream);
CFWriteStreamClose(writeStream);
return;
}
}
Everything is ok when i run it on Ios Application (Default setting by Xcode when create new project)
But when i copy that source code to project create by Cocos2dx.
I got an error at this line:
char *punchline = info;
Error message:
Can not initialize a variable of type 'char *' with an Ivalue of type 'void *'
I don't know which setting should be change to run it.
Thanks.

IOS UDP recvfrom works when in Blocking but not when Non-Bocking

When I comment out the code that turn off blocking everything works fine, but when I leave the non blocking code in I never get any data from recvfrom. (Received bytes is always 0) Here is the code with the blocking statement commented out. I am new to Xcode and IOS but have created UDP code for .NET.
// Create Socket
int Handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (Handle <=0){
printf("Failed to create socket\n");
}
// Bind Socket
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons((unsigned short) 4966);
if (bind(Handle,(struct sockaddr *) &address, sizeof(struct sockaddr_in))< 0){
printf("Failed to Bind\n");
}//end if
printf("Bind Done\n");
// Set to non Blocking
int NonBlocking = 1;
//if (fcntl(Handle, F_SETFL, O_NONBLOCK, NonBlocking) == -1){
printf("Faile to set nonblocking\n");
//}
Boolean ContinueLoop = true;
unsigned char Packet_Data[256];
unsigned int Maximum_Packet_Size = sizeof(Packet_Data);
struct sockaddr_in From_Address;
socklen_t FromLength = sizeof(From_Address);
while (ContinueLoop){
int Received_Bytes = recvfrom(Handle, (char *)Packet_Data, Maximum_Packet_Size, 0, (struct sockaddr *)&From_Address, &FromLength);
if (Received_Bytes > 0){
ContinueLoop = false;
printf("Got Data \n");
} else {
perror("Now");
printf(".");
}
close(Handle);
}//wend
Found the problem. I accidentally included the close statement inside the while loop. Moved it out of the loop where it belongs and all is working now. Blocking and nonblocking.

Port availability check on remote system

How can I tell if a given port is available or not on a local or remote system, in an NSIS page?
Abuot COM ports:
They cannot be detected directly from NSIS so write simple plug-in in C which will detect port by it's number.
This is my basic idea:
void GetListOfLocalPorts(CList<CString, CString>& o_lstPorts)
{
for( int i = 1; i <= 99; i++ )
{
DCB dcb;
HANDLE hCom = NULL;
BYTE byPort = (BYTE)i;
CString strPort;
strPort.Format("COM%d", i);
CString strCom = (CString)"\\\\.\\" + strPort;
SetErrorMode(SEM_FAILCRITICALERRORS);
try
{
hCom = CreateFile(strCom, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hCom == INVALID_HANDLE_VALUE)
continue;
BOOL fSuccess = GetCommState(hCom, &dcb);
CloseHandle(hCom);
if (!fSuccess)
continue;
// Port exists on this machine
o_lstPorts.AddTail(strPort);
}
catch(...)
{
}
}
}

Resources