iOS - BSDSocket 的使用

简介: 1、BSDSocket一套 unix 系统下的 socket API(纯 C)。iOS 系统基于 unix,所以支持底层的 BSD Socket,在 Xcode 中可以直接使用。2、基本使用2.

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];
            });
        }

    Socket5Socket6

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];
            });
        }

    Socket7Socket10

目录
相关文章
|
17天前
|
人工智能 程序员 API
iOS|记一名 iOS 开发新手的前两次 App 审核经历
啥,这玩意也有新手保护期?
20 0
|
1月前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
65 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
2月前
|
iOS开发 开发者
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
172 67
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
|
3月前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
124 11
|
3月前
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
161 66
|
3月前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
194 3
|
3月前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
4月前
|
存储 前端开发 Swift
探索iOS开发:从新手到专家的旅程
本文将带您领略iOS开发的奇妙之旅,从基础概念的理解到高级技巧的掌握,逐步深入iOS的世界。文章不仅分享技术知识,还鼓励读者在编程之路上保持好奇心和创新精神,实现个人成长与技术突破。
|
4月前
|
安全 IDE Swift
探索iOS开发之旅:从初学者到专家
在这篇文章中,我们将一起踏上iOS开发的旅程,从基础概念的理解到深入掌握核心技术。无论你是编程新手还是希望提升技能的开发者,这里都有你需要的指南和启示。我们将通过实际案例和代码示例,展示如何构建一个功能齐全的iOS应用。准备好了吗?让我们一起开始吧!

热门文章

最新文章

  • 1
    uniapp云打包ios应用证书的获取方法,生成指南
    27
  • 2
    iOS|解决 setBrightness 调节屏幕亮度不生效的问题
    117
  • 3
    iOS|记一名 iOS 开发新手的前两次 App 审核经历
    20
  • 4
    iOS各个证书生成细节
    36
  • 5
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    161
  • 6
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    55
  • 7
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    73
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    54
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    65
  • 10
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    172