TCP协议连接方法

#define SOCKET_PORT  9345    (服务器端口号)
#define SOCKET_IP    @"222.137.116.11"  (ip地址)



//打开socket连接 长连接  双向的 (只需要该变 端口号 和  ip地址)
- (void) connectToServer
{
    //self 一个任意指针的数据,可以用在创建CFSocket对象时相关联。这个指针被传递给所有的上下文中定义的回调。
    CFSocketContext CTX = {0, self, NULL, NULL, NULL};
   
    _socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketConnectCallBack, TCPServerConnectCallBack, &CTX);
   
    if (NULL == _socket)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"创建套接字失败" delegate:nil cancelButtonTitle:@"关闭" otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
   
   
    //sockaddr_in 配置socket的连接信息
    struct sockaddr_in addr4;
    //初始化addr4的内存
    memset(&addr4, 0, sizeof(addr4));
    //bzero(&addr4, sizeof(addr4));
    addr4.sin_len = sizeof(addr4);
    //AF_INET  ipv4
    addr4.sin_family = AF_INET;
    //将一个无符号短整型数值转换为网络字节序,即大端模式(big-endian)
    addr4.sin_port = htons(SOCKET_PORT);
    //将一个点分十进制的IP转换成一个长整数型数INET_ADDR()。
    addr4.sin_addr.s_addr = inet_addr([SOCKET_IP UTF8String]);
    // 把sockaddr_in结构体中的地址转换为Data
    CFDataRef address = CFDataCreate(kCFAllocatorDefault, (UInt8 *)&addr4, sizeof(addr4));
    // address CFDataRef类型的包含上面socket的远程地址的对象
    CFSocketConnectToAddress(_socket, address, -1);
   
    CFRunLoopRef cfrl = CFRunLoopGetCurrent();// 获取当前线程的循环
    //创建一个循环,但并没有真正加如到循环中,需要调用CFRunLoopAddSource
    CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _socket, 0);
    //
    CFRunLoopAddSource(cfrl, source, kCFRunLoopCommonModes);
    CFRelease(source);
}


//启动连接服务器后,会回调此方法
static void TCPServerConnectCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
   
    // 当socket为kCFSocketConnectCallBack时,失败时回调失败会返回一个错误代码指针(data),其他情况返回NULL
    if (data != NULL)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"连接失败" delegate:nil cancelButtonTitle:@"关闭" otherButtonTitles:nil];
        [alert show];
        [alert release];
        return;
    }
    //info  跟CFSocketContext CTX = {0, self, NULL, NULL, NULL};
    //第二个参数对应。
    LPSocketEngine *infoObject = (LPSocketEngine *)info;
   
    [infoObject userLogin];
    //其效果与 NSThread 的 detachNewThreadSelector:toTarget:withObject: 是一样的。
    [infoObject performSelectorInBackground:@selector(readStream) withObject:nil];
}

posted on 2012-07-17 20:14  一梦浮生2012  阅读(354)  评论(0编辑  收藏  举报