1、BSDSocket

  • 一套 unix 系统下的 socket API(纯 C)。

  • iOS 系统基于 unix,所以支持底层的 BSD Socket,在 Xcode 中可以直接使用。

2、基本使用

2.1 Client 客户端

  • TCP 客户端

    • 包含头文件

      	#import <sys/socket.h>
      #import <netinet/in.h>
      #import <arpa/inet.h>
      #import <ifaddrs.h>
    • 创建 Socket

      	// client Socket
      @property (nonatomic, assign) int clientSocket; self.clientSocket = socket(AF_INET, SOCK_STREAM, 0); if (self.clientSocket > 0) {
      NSLog(@"Socket 创建成功 %d", self.clientSocket);
      } else {
      NSLog(@"Socket 创建失败");
      }
    • 连接到服务器

      	// 创建服务器地址结构体
      struct sockaddr_in serverAddress;
      bzero(&serverAddress, sizeof(serverAddress));
      serverAddress.sin_family = AF_INET; // 协议族
      serverAddress.sin_port = htons(12345); // 端口 端口数据高位在前低位在后 12345 => 3039 => 3930
      serverAddress.sin_addr.s_addr = inet_addr("192.168.88.100"); // inet_addr 函数可以把 ip 地址转换成一个整数 int isConnected = connect(self.clientSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)); if (isConnected) {
      NSLog(@"连接失败 %d", isConnected);
      } else {
      NSLog(@"连接成功");
      }
    • 发送数据

      	NSString *message = @"你好";
      
      	ssize_t sendLen = send(self.clientSocket, message.UTF8String, strlen(message.UTF8String), 0);
      
      	if (sendLen > 0) {
      NSLog(@"发送成功,发送 %ld 个字节数据", sendLen);
      } else {
      NSLog(@"发送失败 %zd", sendLen);
      }
    • 接收数据

      	// 接收字符串的数组,typedef unsigned char uint8_t;
      uint8_t buffer[1024]; ssize_t recvLen = recv(self.clientSocket, buffer, sizeof(buffer), 0); if (recvLen > 0) { // 按照服务器返回的长度,从 buffer 中,读取二进制数据,建立 NSData 对象
      NSData *data = [NSData dataWithBytes:buffer length:recvLen];
      NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"接收成功,接收到 %ld 个字节数据\n 接收到:%@", recvLen, str);
      } else {
      NSLog(@"接收失败 %zd", recvLen);
      }
    • 关闭连接

      	// 数据传递完毕之后,关闭连接
      int isCloseed = close(self.clientSocket); NSLog(@"%d", isCloseed);

2.2 Server 服务端

  • TCP 服务端

    • 包含头文件

      	#import <sys/socket.h>
      #import <netinet/in.h>
      #import <arpa/inet.h>
      #import <ifaddrs.h>
    • 创建 Socket

      	// server Socket
      @property (nonatomic, assign) int serverSocket; // client Socket
      @property (nonatomic, assign) int clientSocket; self.serverSocket = socket(AF_INET, SOCK_STREAM, 0); if (self.serverSocket > 0) {
      NSLog(@"Socket 创建成功 %d", self.serverSocket);
      } else {
      NSLog(@"Socket 创建失败");
      }
    • 开始监听

      	// 创建服务器地址结构体
      struct sockaddr_in serverAddress;
      bzero(&serverAddress, sizeof(serverAddress));
      serverAddress.sin_family = AF_INET;
      serverAddress.sin_port = htons(12345);
      serverAddress.sin_addr.s_addr = inet_addr("192.168.88.100"); int isBind = bind(self.serverSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)); if (isBind) {
      NSLog(@"绑定失败 %d", isBind);
      return;
      } else {
      NSLog(@"绑定成功");
      } int isListen = listen(self.serverSocket, 10); if (isListen) {
      NSLog(@"监听失败 %d", isListen);
      return;
      } else {
      NSLog(@"监听成功");
      } // clientSocket
      struct sockaddr_in clientAddress;
      bzero(&clientAddress, sizeof(clientAddress));
      socklen_t len = sizeof(clientAddress); self.clientSocket = accept(self.serverSocket, (struct sockaddr *)&clientAddress, &len); if (self.clientSocket) {
      NSLog(@"接收成功 %d,client IP:%zd", self.clientSocket, clientAddress);
      } else {
      NSLog(@"接收失败");
      }
    • 发送数据

      	NSString *message = @"你好";
      
      	// 使用 clientSocket
      ssize_t sendLen = send(self.clientSocket, message.UTF8String, strlen(message.UTF8String), 0); if (sendLen > 0) {
      NSLog(@"发送成功,发送 %ld 个字节数据", sendLen);
      } else {
      NSLog(@"发送失败 %zd", sendLen);
      }
    • 接收数据

      	// 接收字符串的数组,typedef unsigned char uint8_t;
      uint8_t buffer[1024]; // 使用 clientSocket
      ssize_t recvLen = recv(self.clientSocket, buffer, sizeof(buffer), 0); if (recvLen > 0) { // 按照服务器返回的长度,从 buffer 中,读取二进制数据,建立 NSData 对象
      NSData *data = [NSData dataWithBytes:buffer length:recvLen];
      NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"接收成功,接收到 %ld 个字节数据\n 接收到:%@", recvLen, str);
      } else {
      NSLog(@"接收失败 %zd", recvLen);
      }
    • 关闭连接

      	// 数据传递完毕之后,关闭连接
      int isCloseed = close(self.serverSocket); NSLog(@"%d", isCloseed);

3、网络访问

  • 1、请求:

    • 1)请求行

      • GET / HTTP/1.1

      • 方法 GET

      • 路径 /

      • 协议 HTTP 1.1

    • 2)请求头

      • Host: localhost 主机
      • User-Agent: 告诉服务器客户端的类型
      • Accept: 告诉服务器客户端支持的格式
      • Accept-Language: 告诉服务器客户端的语言
      • Accept-Encoding: 告诉服务器客户端支持的压缩格式
  • 2、响应:

    • 1)状态行

      • HTTP/1.1 200 OK

        • 协议 HTTP 1.1
        • 状态码:
          • 200 成功
          • 404 页面没找到
          • 301 内容没变化,用在缓存
    • 2)响应头(主要在开发下载应用的时候使用的)

      • Date: Tue, 24 Mar 2015 01:52:25 GMT 访问日期
      • Server: Apache/2.4.9 (Unix) 访问服务器的类型
      • Content-Location: index.html.en 访问的文件名
      • Content-Length: 45 访问文件的大小
      • Content-Type: text/html 访问文件的类型
    • 3)数据实体

      • <html><body><h1>It works!</h1></body></html>

      • 访问服务器最需的,相当于 NSURLConnection 异步方法回调中的 data。

  • TCP 客户端

    	// 包含头文件
    #import <sys/socket.h>
    #import <netinet/in.h>
    #import <arpa/inet.h>
    #import <ifaddrs.h> @property (nonatomic, assign) int clientSocket; - (void)socketHttpRequest { // 连接到服务器,80 端口 apache 中就是 http 的协议
    if (![self connection:@"127.0.0.1" port:80]) {
    return;
    } // 创建请求
    NSString *requestStr = @"GET / HTTP/1.1\n"
    "Host: localhost\n"
    "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:36.0) Gecko/20100101 Firefox/36.0\n"
    "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n"
    "Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3\n" // \n 拼接换行,内容由 firefox 浏览器的网络控制面板的原始请求头信息中复制
    "Accept-Encoding: gzip, deflate\n" // 删除最后三行,最后一行加两个 \n\n
    "Connection: keep-alive\n\n"; // 发送接收请求,发送给 web 服务器的请求需要遵守 http 协议
    NSString *recvStr = [self sendAndRecv:requestStr]; NSLog(@"%@", recvStr);
    } /// 创建连接
    - (BOOL)connection:(NSString *)hostText port:(int)port { // 创建 Socket self.clientSocket = socket(AF_INET, SOCK_STREAM, 0); // 连接到服务器 struct sockaddr_in serverAddress;
    bzero(&serverAddress, sizeof(serverAddress));
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(port);
    serverAddress.sin_addr.s_addr = inet_addr(hostText.UTF8String); int isConnected = connect(self.clientSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)); return (isConnected == 0);
    } /// 发送和接收字符串
    - (NSString *)sendAndRecv:(NSString *)message { // 发送数据 send(self.clientSocket, message.UTF8String, strlen(message.UTF8String), 0); // 接收数据 uint8_t buffer[1024]; ssize_t recvLen = recv(self.clientSocket, buffer, sizeof(buffer), 0); NSData *data = [NSData dataWithBytes:buffer length:recvLen];
    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return str;
    }

4、客户端使用

  • TCP 客户端 & UDP

    	// 包含头文件
    #import <sys/socket.h>
    #import <netinet/in.h>
    #import <arpa/inet.h>
    #import <ifaddrs.h> typedef NS_ENUM (NSInteger,ServerType) {
    ServerTypeTCP,
    ServerTypeUDP
    }; @property (weak, nonatomic) IBOutlet UITextField *desIPTF;
    @property (weak, nonatomic) IBOutlet UITextField *desPortTF; @property (weak, nonatomic) IBOutlet UITextField *locIPTF;
    @property (weak, nonatomic) IBOutlet UITextField *locPortTF; @property (weak, nonatomic) IBOutlet UITextView *recvTextView;
    @property (weak, nonatomic) IBOutlet UITextField *sendTF; @property (nonatomic, assign) int clientSockfd;
    @property (nonatomic, assign) int udpSockfd; @property (nonatomic, assign) ServerType serType; - (void)viewDidLoad {
    [super viewDidLoad]; NSString *ip_addr = [self getIPAddress];
    _locIPTF.text = ip_addr;
    } #pragma mark - 创建 TCP 连接 - (IBAction)connectTCPServer:(id)sender { [NSThread detachNewThreadSelector:@selector(connectTCPSer) toTarget:self withObject:nil];
    } - (void)connectTCPSer { self.serType = ServerTypeTCP; BOOL success;
    int err; // 创建 socket
    self.clientSockfd = socket(AF_INET, SOCK_STREAM, 0);
    success = (self.clientSockfd != -1); NSString *logStr = nil; if (success == NO) { logStr = @"创建 socket 失败...\n";
    [self showMessage:logStr]; return; } else { logStr = @"创建 socket 成功...\n";
    [self showMessage:logStr]; // 服务器地址
    struct sockaddr_in ser_addr;
    memset(&ser_addr, 0, sizeof(ser_addr));
    ser_addr.sin_len = sizeof(ser_addr);
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_port = htons(_desPortTF.text.intValue);
    ser_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); // 连接
    err = connect(self.clientSockfd, (struct sockaddr *)&ser_addr, sizeof(ser_addr));
    success = (err == 0);
    } if (success == NO) { logStr = @"socket 连接失败...\n";
    [self showMessage:logStr]; return; } else { logStr = [NSString stringWithFormat:@"socket 连接 %@ 成功...\n", _desIPTF.text];
    [self showMessage:logStr]; char buf[1024];
    do {
    // 接收数据
    ssize_t recvLen = recv(self.clientSockfd, buf, sizeof(buf), 0); if (recvLen > 0) {
    logStr = [NSString stringWithFormat:@"recv:%@\n", [NSString stringWithUTF8String:buf]];
    [self showMessage:logStr];
    } } while (strcmp(buf, "exit") != 0);
    }
    } #pragma mark - 创建 UDP 连接 - (IBAction)connectUDP:(id)sender { [NSThread detachNewThreadSelector:@selector(connectUDP) toTarget:self withObject:nil];
    } - (void)connectUDP { self.serType = ServerTypeUDP; BOOL success;
    int err; // 创建 Socket
    self.udpSockfd = socket(AF_INET, SOCK_DGRAM, 0);
    success = (self.udpSockfd != -1); NSString *logStr = nil; if (success == NO) { logStr = @"创建 socket 失败...\n";
    [self showMessage:logStr]; return; } else { logStr = @"创建 socket 成功...\n";
    [self showMessage:logStr]; // 本地地址
    struct sockaddr_in loc_addr;
    bzero(&loc_addr, sizeof(loc_addr));
    loc_addr.sin_port = htons(_locPortTF.text.intValue);
    loc_addr.sin_addr.s_addr = inet_addr(_locIPTF.text.UTF8String); // 绑定
    err = bind(self.udpSockfd, (const struct sockaddr *)&loc_addr, sizeof(loc_addr));
    success = (err == 0);
    } if (success == NO) { logStr = @"socket 绑定失败...\n";
    [self showMessage:logStr]; return; } else { logStr = @"socket 绑定成功...\n";
    [self showMessage:logStr]; // 目标地址
    struct sockaddr_in des_addr;
    bzero(&des_addr, sizeof(des_addr));
    des_addr.sin_family = AF_INET;
    des_addr.sin_port = htons(_desPortTF.text.intValue);
    des_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); char buf[256];
    bzero(buf, sizeof(buf)); while(1) { // 接收数据
    socklen_t des_addr_len = sizeof(des_addr);
    ssize_t recvLen = recvfrom(self.udpSockfd, buf, sizeof(buf), 0, (struct sockaddr*)&des_addr, &des_addr_len); if (recvLen > 0) {
    logStr = [NSString stringWithFormat:@"recv:%@\n", [NSString stringWithUTF8String:buf]];
    [self showMessage:logStr];
    }
    }
    }
    } #pragma mark - 发送数据 - (IBAction)btnClick:(id)sender { if (_sendTF.text.length == 0) {
    return;
    } else { ssize_t sendLen; if (self.serType == ServerTypeTCP) { // 发送数据
    sendLen = send(self.clientSockfd, _sendTF.text.UTF8String, strlen(_sendTF.text.UTF8String), 0); } else if (self.serType == ServerTypeUDP) { // 目标地址
    struct sockaddr_in des_addr;
    bzero(&des_addr, sizeof(des_addr));
    des_addr.sin_family = AF_INET;
    des_addr.sin_port = htons(_desPortTF.text.intValue);
    des_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); // 发送数据
    sendLen = sendto(self.udpSockfd, _sendTF.text.UTF8String, strlen(_sendTF.text.UTF8String), 0,
    (struct sockaddr *)&des_addr, sizeof(des_addr));
    } if (sendLen > 0) {
    NSString *logStr = [NSString stringWithFormat:@"send:%@\n", _sendTF.text];
    [self showMessage:logStr];
    }
    }
    } #pragma mark - 获取本地 IP 地址 - (NSString *)getIPAddress { NSString *address = @"error";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0; // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces
    temp_addr = interfaces; while (temp_addr != NULL) { if (temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone
    if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String
    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
    }
    }
    temp_addr = temp_addr->ifa_next;
    }
    } // Free memory
    freeifaddrs(interfaces);
    return address;
    } // 显示信息
    - (void)showMessage:(NSString *)msg { dispatch_async(dispatch_get_main_queue(), ^{ _recvTextView.text = [_recvTextView.text stringByAppendingString:msg];
    });
    }

5、服务端使用

  • TCP 服务端 & UDP

    	// 包含头文件
    #import <sys/socket.h>
    #import <netinet/in.h>
    #import <arpa/inet.h>
    #import <ifaddrs.h> typedef NS_ENUM (NSInteger,ServerType) {
    ServerTypeTCP,
    ServerTypeUDP
    }; @property (weak, nonatomic) IBOutlet UITextField *desIPTF;
    @property (weak, nonatomic) IBOutlet UITextField *desPortTF; @property (weak, nonatomic) IBOutlet UITextField *locIPTF;
    @property (weak, nonatomic) IBOutlet UITextField *locPortTF; @property (weak, nonatomic) IBOutlet UITextView *recvTextView;
    @property (weak, nonatomic) IBOutlet UITextField *sendTF; @property (nonatomic, assign) int serverSockfd;
    @property (nonatomic, assign) int clientSockfd; @property (nonatomic, assign) int udpSockfd; @property (nonatomic, assign) ServerType serType; - (void)viewDidLoad {
    [super viewDidLoad]; NSString *ip_addr = [self getIPAddress];
    _locIPTF.text = ip_addr;
    } #pragma mark - 创建 TCP 监听 - (IBAction)createdTCPServer:(id)sender { _desIPTF.enabled = NO;
    _desPortTF.enabled = NO;
    _locPortTF.enabled = NO; [NSThread detachNewThreadSelector:@selector(createdTCPSer) toTarget:self withObject:nil];
    } - (void)createdTCPSer { self.serType = ServerTypeTCP; BOOL success;
    int err; // 创建 socket
    self.serverSockfd = socket(AF_INET, SOCK_STREAM, 0);
    success = (self.serverSockfd != -1); NSString *logStr = nil; if (success == NO) { logStr = @"创建 socket 失败...\n";
    [self showMessage:logStr]; return; } else { logStr = @"创建 socket 成功...\n";
    [self showMessage:logStr]; // 本地地址
    struct sockaddr_in loc_addr;
    memset(&loc_addr, 0, sizeof(loc_addr));
    loc_addr.sin_family = AF_INET;
    loc_addr.sin_port = htons(_locPortTF.text.intValue);
    loc_addr.sin_addr.s_addr = inet_addr(_locIPTF.text.UTF8String); // 绑定
    err = bind(self.serverSockfd, (const struct sockaddr *)&loc_addr, sizeof(loc_addr));
    success = (err == 0);
    } if (success == NO) { logStr = @"socket 绑定失败...\n";
    [self showMessage:logStr]; return; } else { logStr = @"socket 绑定成功...\n";
    [self showMessage:logStr]; // 监听
    err = listen(self.serverSockfd, 5); // 5:最大连接个数
    success = (err == 0);
    } if (success == NO) { logStr = @"socket 监听失败...\n";
    [self showMessage:logStr]; return; } else { logStr = @"socket 监听成功...\n";
    [self showMessage:logStr]; while (true) { // 循环 // 连接的客户端的地址
    struct sockaddr_in cli_addr;
    socklen_t cli_addr_Len = sizeof(cli_addr); // 接受客户端的请求,并建立连接
    self.clientSockfd = accept(self.serverSockfd, (struct sockaddr *)&cli_addr, &cli_addr_Len);
    success = (self.clientSockfd != -1); if (success) { char *ip_addr = inet_ntoa(cli_addr.sin_addr);
    int ip_port = ntohs(cli_addr.sin_port);
    dispatch_async(dispatch_get_main_queue(), ^{
    _desIPTF.text = [NSString stringWithFormat:@"%s", ip_addr];
    _desPortTF.text = [NSString stringWithFormat:@"%d", ip_port];
    }); logStr = [NSString stringWithFormat:@"已连接:%s,port:%d\n", ip_addr, ip_port];
    [self showMessage:logStr]; char buf[1024];
    do {
    // 返回读取的字节数
    ssize_t recvLen = recv(self.clientSockfd, buf, sizeof(buf), 0); if (recvLen > 0) {
    logStr = [NSString stringWithFormat:@"recv:%@\n", [NSString stringWithUTF8String:buf]];
    [self showMessage:logStr];
    } } while (strcmp(buf, "exit") != 0);
    }
    }
    }
    } #pragma mark - 创建 UDP 连接 - (IBAction)connectUDP:(id)sender { [NSThread detachNewThreadSelector:@selector(connectUDP) toTarget:self withObject:nil];
    } - (void)connectUDP { self.serType = ServerTypeUDP; BOOL success;
    int err; // 创建 Socket
    self.udpSockfd = socket(AF_INET, SOCK_DGRAM, 0);
    success = (self.udpSockfd != -1); NSString *logStr = nil; if (success == NO) { logStr = @"创建 socket 失败...\n";
    [self showMessage:logStr]; return; } else { logStr = @"创建 socket 成功...\n";
    [self showMessage:logStr]; // 本地地址
    struct sockaddr_in loc_addr;
    bzero(&loc_addr, sizeof(loc_addr));
    loc_addr.sin_port = htons(_locPortTF.text.intValue);
    loc_addr.sin_addr.s_addr = inet_addr(_locIPTF.text.UTF8String); // 绑定
    err = bind(self.udpSockfd, (const struct sockaddr *)&loc_addr, sizeof(loc_addr));
    success = (err == 0);
    } if (success == NO) { logStr = @"socket 绑定失败...\n";
    [self showMessage:logStr]; return; } else { logStr = @"socket 绑定成功...\n";
    [self showMessage:logStr]; // 目标地址
    struct sockaddr_in des_addr;
    bzero(&des_addr, sizeof(des_addr));
    des_addr.sin_family = AF_INET;
    des_addr.sin_port = htons(_desPortTF.text.intValue);
    des_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); char buf[256];
    bzero(buf, sizeof(buf)); while(1) { // 接收数据
    socklen_t des_addr_len = sizeof(des_addr);
    ssize_t recvLen = recvfrom(self.udpSockfd, buf, sizeof(buf), 0, (struct sockaddr*)&des_addr, &des_addr_len); if (recvLen > 0) {
    logStr = [NSString stringWithFormat:@"recv:%@\n", [NSString stringWithUTF8String:buf]];
    [self showMessage:logStr];
    }
    }
    }
    } #pragma mark - 发送数据 - (IBAction)btnClick:(id)sender { if (_sendTF.text.length == 0) {
    return;
    } else { ssize_t sendLen; if (self.serType == ServerTypeTCP) { // 发送数据
    sendLen = send(self.clientSockfd, _sendTF.text.UTF8String, strlen(_sendTF.text.UTF8String), 0); } else if (self.serType == ServerTypeUDP) { // 目标地址
    struct sockaddr_in des_addr;
    bzero(&des_addr, sizeof(des_addr));
    des_addr.sin_family = AF_INET;
    des_addr.sin_port = htons(_desPortTF.text.intValue);
    des_addr.sin_addr.s_addr = inet_addr(_desIPTF.text.UTF8String); // 发送数据
    sendLen = sendto(self.udpSockfd, _sendTF.text.UTF8String, strlen(_sendTF.text.UTF8String), 0,
    (struct sockaddr *)&des_addr, sizeof(des_addr));
    } if (sendLen > 0) {
    NSString *logStr = [NSString stringWithFormat:@"send:%@\n", _sendTF.text];
    [self showMessage:logStr];
    }
    }
    } #pragma mark - 获取本地 IP 地址 - (NSString *)getIPAddress { NSString *address = @"error";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0; // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces
    temp_addr = interfaces; while (temp_addr != NULL) { if (temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone
    if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String
    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
    }
    }
    temp_addr = temp_addr->ifa_next;
    }
    } // Free memory
    freeifaddrs(interfaces);
    return address;
    } // 显示信息
    - (void)showMessage:(NSString *)msg { dispatch_async(dispatch_get_main_queue(), ^{ _recvTextView.text = [_recvTextView.text stringByAppendingString:msg];
    });
    }

iOS - BSDSocket 的使用的更多相关文章

  1. 聊聊iOS中网络编程长连接的那些事

    1.长连接在iOS开发中的应用 常见的短连接应用场景:一般的App的网络请求都是基于Http1.0进行的,使用的是NSURLConnection.NSURLSession或者是AFNetworking ...

  2. iOS即时通讯之CocoaAsyncSocket源码解析一

    申明:本文内容属于转载整理,原文连接 前言: CocoaAsyncSocket是谷歌的开发者,基于BSD-Socket写的一个IM框架,它给Mac和iOS提供了易于使用的.强大的异步套接字库,向上封装 ...

  3. iOS可视化动态绘制连通图

    上篇博客<iOS可视化动态绘制八种排序过程>可视化了一下一些排序的过程,本篇博客就来聊聊图的东西.在之前的博客中详细的讲过图的相关内容,比如<图的物理存储结构与深搜.广搜>.当 ...

  4. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

  5. 【疯狂造轮子-iOS】JSON转Model系列之一

    [疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...

  6. iOS总结_UI层自我复习总结

    UI层复习笔记 在main文件中,UIApplicationMain函数一共做了三件事 根据第三个参数创建了一个应用程序对象 默认写nil,即创建的是UIApplication类型的对象,此对象看成是 ...

  7. iOS代码规范(OC和Swift)

    下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...

  8. JS调用Android、Ios原生控件

    在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...

  9. 告别被拒,如何提升iOS审核通过率(上篇)

    iOS审核一直是每款移动产品上架苹果商店时面对的一座大山,每次提审都像是一次漫长而又悲壮的旅行,经常被苹果拒之门外,无比煎熬.那么问题来了,我们有没有什么办法准确把握苹果审核准则,从而提升审核的通过率 ...

随机推荐

  1. Octave下操作CH341

    #include <octave/oct.h> #include <windows.h> #include <cstdint> #include <fstre ...

  2. 我所遭遇过的游戏中间件--Havok

    我所遭遇过的游戏中间件--Havok Havok是我接触的第一款游戏中间件,那是在五,六年前,我刚刚毕业,对游戏开发还是个菜鸟.我记得先是对游戏场景中的地形和其他静态物体生成刚体,然后做角色的Ragd ...

  3. 第七章 常用Java集合类总结

    7.1.List(允许重复元素) ArrayList: 底层数据结构:Object[] 在查询(get).遍历(iterator).修改(set)使用的比较多的情况下,用ArrayList 可扩容,容 ...

  4. 网站流量分析指标-PV/UV/PR/IP

    网站数据分析,经常会统计一个页面或者一个网站或者其他情况的PV/UV.下面简单说一下,这些量PV/UV/PR/IP. 1.PV PV(page view),即页面浏览量,或点击量.通常是衡量一个网络新 ...

  5. Android之SlideMenu实例Demo

    年末加班基本上一周都没什么时候回家写代码,回到家就想睡觉,周末难得有时间写个博客,上次写了一篇关于SlideMenu开源项目的导入问题,这次主要讲讲使用的问题,SlideMenu应用的广泛程度就不用说 ...

  6. 网上收集:跟着 8 张思维导图学习 Javascript【转】

    学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将po出8张javascript相关的思维导图. 思维导图小tips:思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又 ...

  7. Transform开发cube模型权限处理之不同用户数据的过滤

    ========================此文不再详细的说transform的开发过程====================================================== ...

  8. 相似qq的IM聊天应用源代码

    这个是IM聊天应用源代码,该应用IM支持实现XMPP,以及图片和表情,语音.消息回执等功能,基本覆盖了常见的im应用的功能了,大家能够參考一下吧. 源代码下载:http://code.662p.com ...

  9. 大型应用的javascript架构

    来源:http://blog.leezhong.com/tech/2010/11/29/javascript-arch.html 目前很多网站基本没有明确的前端架构,大多是服务端渲染视图页,输出到浏览 ...

  10. IDEA+Gradle相关资料

    要注意下载的版本,不能过于陈旧,否则会报错,导致无法正常配置. 具体配置参考:https://my.oschina.net/u/1994816/blog/297967 IDEA下载地址:https:/ ...