0

(POSIX/winsocks) ソケットベースの TCP/IP プロトコルのクライアント側をネイティブの 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) で実行されているサーバーとの有効な接続が得られます (ただし、Winsock で行うのとは多少異なる方法で ECONNREFUSED を処理する必要があるようです)。

作成したソケットを 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 フレームワークを使用して細かい制御 (クライアントとサーバーのポート指定、タイムアウト指定など) を利用できない可能性はありますか?

4

1 に答える 1

0

私はそれが少し(年...)古いことを認めなければならず、私にとって本当に優先度の高い問題ではありませんでした.私のコードはまだ実際の使用を見ていません. これが私が最終的に得たものです

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++ モジュールに含まれているため、コードが少しごちゃごちゃしているのがわかりますが、先に進む前に行ったテストでは十分に機能していたようです。

これがお役に立てば幸いです - そして自由に完全なコードを掘り下げてください。

于 2014-06-09T17:59:02.053 に答える