MacOSX: создание CFStream/NSStream с определенными клиентскими и серверными портами

Я пытаюсь перевести клиентскую часть протокола TCP/IP на основе сокетов (POSIX/winsocks) в собственные рамки Mac OS X. В соответствии с этим протоколом клиентский порт устанавливается на указанный порт, а затем этот сокет подключается к серверу через другой порт. В основном (проверка ошибок удалена):

InitCommClient( SOCK *clnt, char *address, unsigned short serverPortNr, unsigned short clientPortNr, int timeOutMS )
{
    CreateClient( clnt, clientPortNr );
    ConnectToServer( *clnt, serverPortNr, address, timeOutMS );
}

CreateClient(SOCK *s, unsigned short port )
{ int yes=1;
    *s = socket( AF_INET, SOCK_STREAM, 0 );
    setsockopt( *s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes) );
    // set up lsock - htons(port), AF_INIT
    bind( *s, (SOCKADDR*)&lsock, sizeof(SOCKADDR_IN) );
    { int delay_flag = fcntl(*s, F_GETFL, 0);
      delay_flag |= O_NONBLOCK;
        fcntl( *s, F_SETFL, delay_flag );
    }
}

CreateServer(SOCK *s, unsigned short port )
{ int yes=1;
    *s = socket( AF_INET, SOCK_STREAM, 0 );
    // set up lsock - htons(port), AF_INIT
    bind( *s, (SOCKADDR*)&lsock, sizeof(SOCKADDR_IN) );
    listen( *s, 3 );
    { int delay_flag = fcntl(*s, F_GETFL, 0);
      delay_flag |= O_NONBLOCK;
        fcntl( *s, F_SETFL, delay_flag );
    }
}

ConnectToServer(SOCK s, unsigned short port, const char *address, int timeOutms)
{
    // set up fsock - inet_addr(address), htons(port), AF_INET
    errSock = connect( s, (SOCKADDR*)&fsock, sizeof(SOCKADDR_IN) );
    // handle EINPROGRESS, EWOULDBLOCK, EISCONN and ECONNREFUSED, waiting for socket to become writable
}

Когда я использую эти функции, я получаю рабочее соединение с сервером, работающим в MS Windows (или под Wine) (хотя может показаться, что мне нужно обрабатывать ECONNREFUSED несколько иначе, чем в winsocks).

Я также могу передать созданный сокет в CFStreamCreatePairWithSocket, чтобы получить функциональную пару NSInputStream, NSOutputStream:

InitCommClient( &sServer, ipAddress, ServerPortNr, ClientPortNr, 50 );
CFStreamCreatePairWithSocket( NULL, sServer, (CFReadStreamRef*) &nsReadServer, (CFWriteStreamRef*) &nsWriteServer );

Можно ли создать эту пару напрямую, и если да, то как? На данный момент мне удалось получить функциональный NSInputStream, используя

CFStreamCreatePairWithSocketToHost( NULL, (CFStringRef) [NSString stringWithUTF8String:ipAddress], ServerPortNr,
                                (CFReadStreamRef*) &nsReadServer, (CFWriteStreamRef*) &nsWriteServer );

Возможно ли, что точный контроль (спецификация портов клиента и сервера, спецификация тайм-аута и т. д.) недоступен с использованием высокоуровневой инфраструктуры CFStream/NSStream?


person RJVB    schedule 07.06.2013    source источник
comment
Удалось ли вам добиться успеха, потому что у меня сейчас такая же проблема.   -  person Jashugan    schedule 09.06.2014


Ответы (1)


Я должен признать, что ему немного (год...) не хватает времени, и он никогда не был для меня действительно приоритетной проблемой, и мой код еще не видел никакого реального использования. Это то, что я закончил с

NSInputStream *nsReadServer = NULL;
NSOutputStream *nsWriteServer = NULL;

void commsInit(const char *ipAddress)
{
    InitCommClient( &sServer, ipAddress, ServerPortNr, ClientPortNr, 50 );
    if( sServer != NULLSOCKET ){
        CFStreamCreatePairWithSocket( NULL, sServer, (CFReadStreamRef*) &nsReadServer, (CFWriteStreamRef*) &nsWriteServer );
        [nsReadServer retain]; [nsWriteServer retain];
        [nsReadServer setDelegate:[[OurStreamDelegate alloc] init] ];
        [nsReadServer scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [nsReadServer open]; [nsWriteServer open];
    }
}

Я вижу, что код немного беспорядочный, поскольку InitCommClient находится в модуле C++, но, по-видимому, он работал достаточно хорошо во время тестирования, которое я провел, прежде чем двигаться дальше.

Надеюсь, это поможет — и не стесняйтесь копаться в полный код .

person RJVB    schedule 09.06.2014