socket 初探

来源:互联网 发布:水平垂直居中 知乎 编辑:程序博客网 时间:2024/04/29 08:47

1.在项目里倒入:

  CFNetwork.framework ,SystemConfiguration.framework
#import <sys/socket.h>#import <netinet/in.h>#import <arpa/inet.h>#import <unistd.h>
-(void)CreateConnect:(NSString*)strAddress{    CFSocketContext sockContext = {0, // 结构体的版本,必须为0        self,        NULL, // 一个定义在上面指针中的retain的回调, 可以为NULL        NULL,        NULL};    _socket = CFSocketCreate(kCFAllocatorDefault, // 为新对象分配内存,可以为nil                             PF_INET, // 协议族,如果为0或者负数,则默认为PF_INET                             SOCK_STREAM, // 套接字类型,如果协议族为PF_INET,则它会默认为SOCK_STREAM                             IPPROTO_TCP, // 套接字协议,如果协议族是PF_INET且协议是0或者负数,它会默认为IPPROTO_TCP                             kCFSocketConnectCallBack, // 触发回调函数的socket消息类型,具体见Callback Types                             TCPClientConnectCallBack, // 上面情况下触发的回调函数                             &sockContext // 一个持有CFSocket结构信息的对象,可以为nil                             );    if(_socket != NULL)    {        struct sockaddr_in addr4;   // IPV4        memset(&addr4, 0, sizeof(addr4));        addr4.sin_len = sizeof(addr4);        addr4.sin_family = AF_INET;        addr4.sin_port = htons(8002);        addr4.sin_addr.s_addr = inet_addr([strAddress UTF8String]);  // 把字符串的地址转换为机器可识别的网络地址        // 把sockaddr_in结构体中的地址转换为Data        CFDataRef address = CFDataCreate(kCFAllocatorDefault, (UInt8 *)&addr4, sizeof(addr4));        CFSocketConnectToAddress(_socket, // 连接的socket                                 address, // CFDataRef类型的包含上面socket的远程地址的对象                                 -1  // 连接超时时间,如果为负,则不尝试连接,而是把连接放在后台进行,如果_socket消息类型为kCFSocketConnectCallBack,将会在连接成功或失败的时候在后台触发回调函数                                 );        CFRunLoopRef cRunRef = CFRunLoopGetCurrent();    // 获取当前线程的循环        // 创建一个循环,但并没有真正加如到循环中,需要调用CFRunLoopAddSource        CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _socket, 0);        CFRunLoopAddSource(cRunRef, // 运行循环                           sourceRef,  // 增加的运行循环源, 它会被retain一次                           kCFRunLoopCommonModes  // 增加的运行循环源的模式                           );        CFRelease(sourceRef);        NSLog(@"connect ok");    }}// socket回调函数,同客户端static void TCPClientConnectCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info){     ViewController *client = (ViewController *)info;    if (data != NULL)    {        NSLog(@"连接失败");        [client.TextView insertText:@"连接失败\n"];        return;    }    else    {        NSLog(@"连接成功");        [client.TextView insertText:@"连接成功\n"];        // 读取接收的数据        g_viewPage = client;        [client StartReadThread];    }}-(void)StartReadThread{    NSThread *InitThread = [[NSThread alloc]initWithTarget:self selector:@selector(InitThreadFunc:) object:self];    [InitThread start];}-(void)InitThreadFunc:(id)sender{    while (1) {        [self readStream];    }} // 读取接收的数据-(void)readStream{    char buffer[1024];    NSString *str = @"服务器发来数据:";    recv(CFSocketGetNative(_socket), buffer, sizeof(buffer), 0);    {        NSString * str2 = [NSString stringWithUTF8String:buffer];//        str = [str stringByAppendingString:[NSString stringWithUTF8String:buffer]];        if (str2) {            str = [str stringByAppendingString:str2];        }    }    NSLog(@"%@",str);//    NSLog(str);    //回界面显示信息    [self performSelectorOnMainThread:@selector(ShowMsg:) withObject:str waitUntilDone:NO];}-(void)ShowMsg:(id)sender{    NSString *str = sender;    str = [str stringByAppendingString:@"\n"];    [self.TextView insertText:str];} // 发送数据- (void)sendMessage {    NSLog(@"hello Server");    char *data = "hello";    NSString *str = @"{\"name\":\"yaofeng\"}";    send(CFSocketGetNative(_socket), data, strlen(data) + 1, 0);//    send(CFSocketGetNative(_socket), str, str.length , 0);}- (IBAction)SendMessageTouch:(id)sender {    [self sendMessage];}- (IBAction)TouchConnectServer:(id)sender {    NSString *serverIp = self.textField.text;     [self CreateConnect:serverIp];}

这里写图片描述
这里写图片描述
这里写图片描述

0 0
原创粉丝点击