iOSソケットプログラミング(入門)


1.CベースBSDソケット(UNIXシステムで共通のネットワークインタフェース)
BSDソケットは最も理解しやすく、入門しやすく、最も柔軟だが最も使いにくいと感じています.特に大規模なプロジェクトでは
ヘッダファイルをインポートする必要があります
#import <sys/socket.h>
#import <netdb.h>

サーバ側
    int    listenfd, connfd;
    struct sockaddr_in     servaddr;
    char    buff[4096];
    long     n;
    int i=100;
    
    //   socket
    if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
        printf("create socket error: %s(errno: %d)
",strerror(errno),errno); return; } // ip memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(8088);// // if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){ printf("bind socket error: %s(errno: %d)
",strerror(errno),errno); return; } // if( listen(listenfd, 10) == -1){ printf("listen socket error: %s(errno: %d)
",strerror(errno),errno); return; } // printf("======waiting for client's request======
"); while(i>0){ if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){ printf("accept socket error: %s(errno: %d)",strerror(errno),errno); continue; } n = recv(connfd, buff, MAXLINE, 0); buff[n] = '\0'; printf("recv msg from client: %s
", buff); close(connfd); } // socket close(listenfd);

クライアント
-(void)sendDataToServerURL:(NSURL *)url{
    int    sockfd;
    char    sendline[4096];
    struct sockaddr_in    servaddr;
    NSString * host = [url host];

    
    //   socket
    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        printf("create socket error: %s(errno: %d)
", strerror(errno),errno); return; } // ip struct hostent * hostEnt = gethostbyname([host UTF8String]);// ip if (NULL == hostEnt) { NSLog(@" "); return; } struct in_addr * remoteInAddr = (struct in_addr *)hostEnt->h_addr_list[0]; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(8088); servaddr.sin_addr = *remoteInAddr; // TCP ( ip ) if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ printf("connect error: %s(errno: %d)
",strerror(errno),errno); return; } // TCP printf("send msg to server:
"); fgets(sendline, 4096, stdin); if(send(sockfd, sendline, strlen(sendline), 0) < 0) { printf("send msg error: %s(errno: %d)
", strerror(errno), errno); return; } // socket close(sockfd); }

2.FCSocketインタフェースはBSDソケットより多い
サーバ側とBSDソケットは少し似ていますが、
クライアントはBSDソケットとは全く異なり、入出力ストリームを使用しています.
サーバ側
//      
static void handleConnect(CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
    NSLog(@"     ");
}
-(void)openFCSocket
{
    //   socket
    const CFSocketContext socketCtxt = {0, (__bridge void *)self, NULL, NULL, NULL};
    CFSocketRef  cfSocket = CFSocketCreate(
                                           kCFAllocatorDefault,
                                           PF_INET,
                                           SOCK_STREAM,
                                           IPPROTO_TCP,
                                           kCFSocketAcceptCallBack,
                                           (CFSocketCallBack)handleConnect,//      
                                           &socketCtxt);
    
    if (cfSocket == NULL) {
        NSLog(@"  Socket  ");
        return;
    }
    
    
    //   ip  
    struct sockaddr_in sin;
    memset(&sin, 0, sizeof(sin));
    sin.sin_len = sizeof(sin);
    sin.sin_family = AF_INET; /* Address family */
    sin.sin_port = htons(8088); /* Or a specific port */
    sin.sin_addr.s_addr= INADDR_ANY;
    
    
    //       
    CFDataRef sincfd = CFDataCreate(
                                    kCFAllocatorDefault,
                                    (UInt8 *)&sin,
                                    sizeof(sin));
    
    if (kCFSocketSuccess != CFSocketSetAddress(cfSocket, sincfd)) {
        NSLog(@"        ");
    }
    CFRelease(sincfd);
    
    
    // socket    run loop
    CFRunLoopSourceRef socketsource = CFSocketCreateRunLoopSource(
                                                                  kCFAllocatorDefault,
                                                                  cfSocket,
                                                                  0);
    CFRunLoopAddSource(
                       CFRunLoopGetCurrent(),
                       socketsource,
                       kCFRunLoopDefaultMode);

}

クライアント
    NSString *host = @"127.0.0.1";
    int port = 8088;

    //        
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host,
                                       port, &readStream, &writeStream);
    NSInputStream *inputStream = (__bridge NSInputStream *)readStream;
    NSOutputStream *outputStream = (__bridge NSOutputStream *)writeStream;

    
    if (inputStream == nil || outputStream == nil) {
        NSLog(@"     !");
        return ;
    }
    
    //        
    [inputStream open];
    [outputStream open];
    
    
    //    
    NSData *outgoingDataBuffer =  [@"testdata" dataUsingEncoding:NSUTF8StringEncoding];
    NSInteger writtenBytes = [outputStream write:outgoingDataBuffer.bytes maxLength:outgoingDataBuffer.length];
    if ( writtenBytes == -1 ) {
        NSLog(@"    ");
        return;
    }
    NSLog(@"    ");

3.CocoaAsyncSocketパッケージCFSocket
TCP、UDP、非同期スレッドの追加、切り離し再接続、TLS/SSLなど、実開発で実現するものを実現しました.
車輪を繰り返す時間がなければ、このようなサードパーティ製のフレームを使うのもいいです.