[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fSYdvpEUZ1AlS420hJu7uQtrrVvMIFEmLpbeq0JjAb80":3},{"code":4,"message":5,"data":6},200,"成功",{"id":7,"createdAt":8,"title":9,"content":10,"summary":11,"image":12,"uid":13,"user":14,"categoryId":21,"category":22,"subCategoryId":24,"subCategory":25,"comments":27,"status":17,"reason":12,"notice":12,"visitCount":28,"commentCount":29,"keywords":30},69,"2024-02-02T10:36:21.708Z","什么是socket，iOS中的Socket如何实现","# Socket\n网络以数据包的形式进行传播\n\n高低电平\n\nOSI网络模型：从7层模型，合并成4层模型\n\n*   OSI的7层模型：\n\n1.  应用层\n2.  表示层\n3.  会话层\n4.  传输层\n5.  网络层\n6.  数据链路层\n7.  物理层\n\n# \n\n*   4层模型\n1.  应用层\n2.  传输层 （tcp， udp）\n3.  网络互联层 （ip）\n4.  网络接口层\n\n# \n*   TCP\n1.  握手，建立传输数据的通道\n2.  可靠，数据大小不受限制，可以进行大数据传输\n3.  安全，可靠协议，安全送达\n4.  应用：数据下载\n# \n*   UDP\n1.  不可靠，只管发送，不确认对方是否收到\n2.  效率高，不需要建立连接\n3.  数据包大小受限制，大小限制在64k之内\n4.  应用：直播、游戏\n\n## socket\n\n每一个端都有socket，通过ip地址进行连接，通过端口号进行通信。\n\n过程：创建socket，建立连接，数据读取，关闭连接\n\n## Example\n\n### 引入头文件\n```\n#import \u003Csys/socket.h>\n#import \u003Cnetinet/in.h>\n#import \u003Carpa/inet.h>\n```\n\n### 模拟本地socket：\n```\n- (void)socketDemo {\n    // 1. 创建socket\n    /**\n     domain:    协议域， AF_INET -> ipv4\n     type:      socket类型，SOCK_STREAM\n     protocol:  IPPROTO_TCP\n     */\n    int clientSocket = socket(AF_INET, SOCK_STREAM, 0);\n    // 2. 连接服务器\n    /**\n    1 > 客户端socket\n    2 > 服务器ip地址结构体的指针\n    3 > 结构体数据的长度\n    返回值：0表示成功\n    */\n    struct sockaddr_in serverAddr;\n    serverAddr.sin_family = AF_INET;\n    serverAddr.sin_port = htons(12345);\n    serverAddr.sin_addr.s_addr = inet_addr(\"127.0.0.1\");\n    \n    \n    int connResult = connect(clientSocket, (const struct sockaddr *)&serverAddr, sizeof(serverAddr));\n    if (connResult == 0) { // Success\n        NSLog(@\"连接成功\");\n    } else { // fail\n        NSLog(@\"失败码 %d\", connResult);\n    }\n    // 3. 发送数据\n    /**\n    1. 客户端socket\n    2. 发送内容的地址\n    3. 发送内容长度\n    4. 发送方式标志，一般为0\n    返回值：成功后发送的字节数，失效则返回SOCKET_ERROR\n    */\n    NSString *sendMsg = @\"Hello\";\n    ssize_t sendLen = send(clientSocket, sendMsg.UTF8String, strlen(sendMsg.UTF8String), 0);\n    NSLog(@\"发送了 %ld 个字节\", sendLen);\n    \n    // 4. 从服务器接收数据\n    /**\n    1. 客户端socket\n    2. 接收内容的缓冲区地址\n    3. 接收内容缓存区长度\n    4. 接收方式，0表示阻塞，必须等待服务器返回数据\n    返回值：如果成功，则返回读入的字节数，失效则返回SOCKET_ERROR\n    */\n    uint8_t buffer[1024]; // 准备空间\n    ssize_t recvLen = recv(clientSocket, buffer, sizeof(buffer), 0);\n    NSLog(@\"接收了 %ld 个字节\", recvLen);\n    \n    NSData *data = [NSData dataWithBytes:buffer length:recvLen];\n    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];\n    NSLog(@\"%@\", str);\n    \n    // 5. close\n    close(clientSocket);\n}\n```\n\n> 可以在terminal终端执行命令：`nc -lk 端口号`，始终监听本地计算机“端口号”的数据。Netcat是终端下用于调试和检查网络的工具包，可用于创建TCP/IP连接。\n\n### 连接和发送/接收消息\n```\n@property (nonatomic, assign) int clientSocket;\n```\n```\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    // Do any additional setup after loading the view.\n    \n//    [self socketDemo];\n    \n    [self doConnectionWithPort:80 addr:\"61.135.169.121\"];\n//    [self sendMsg:@\"我要奋斗!!\"];\n    NSString *request = @\"GET / HTTP/1.1\\n\"\n    \"Host: www.baidu.com\\n\\n\";\n    [self sendMsg:request];\n}\n\n- (void)doConnectionWithPort:(int)port addr:(const char *)addr {\n    _clientSocket = socket(AF_INET, SOCK_STREAM, 0);\n    struct sockaddr_in serverAddr;\n    serverAddr.sin_family = AF_INET;\n    serverAddr.sin_port = htons(port);\n    serverAddr.sin_addr.s_addr = inet_addr(addr);\n    \n    \n    int connResult = connect(_clientSocket, (const struct sockaddr *)&serverAddr, sizeof(serverAddr));\n    if (connResult == 0) { // Success\n        NSLog(@\"连接成功\");\n    } else { // fail\n        NSLog(@\"失败码 %d\", connResult);\n    }\n    \n}\n\n- (void)sendMsg:(NSString *)sendMsg {\n    // 3. 发送数据\n    ssize_t sendLen = send(_clientSocket, sendMsg.UTF8String, strlen(sendMsg.UTF8String), 0);\n    NSLog(@\"发送了 %ld 个字节\", sendLen);\n    \n    \n    // 4. 从服务器接收数据\n    \n    uint8_t buffer[1024]; // 准备空间\n    ssize_t recvLen = recv(_clientSocket, buffer, sizeof(buffer), 0);\n    NSLog(@\"接收了 %ld 个字节\", recvLen);\n    \n    NSData *data = [NSData dataWithBytes:buffer length:recvLen];\n    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];\n    NSLog(@\"%@\", str);\n    \n    \n}\n\n- (void)closeSocket {\n    // 5. close\n    close(_clientSocket);\n}\n```\n\n## 网络\n苹果的connection有一些地方做的不是很好，比如异步下载，数据回调不来，runloop默认不开启。\n线程有任务才有可能不释放。\n\nhttps协议：http + ssl (RSA加密)\n\n> https不会对客户端进行验证\n\n> RSA非对称加密 \\\n> 公钥，私钥 == 长度大概在200位的一串数字 \\\n> 明文公钥加密，私密解密 \\\n> 私钥加密，公钥解密！\n\n> 对称加密 \\\n> 明文密钥加密 -> 密文 \\\n> 密文密钥解密 -> 明文\n\n> 加盐\n\n1.  一个字符串，通过拼接\n2.  可以使用随机盐，一个客户端一个盐，保证安全\n3.  也可以再加上时间戳（服务器给的），来保证安全，服务器验证当前时间或者前1分钟内的数据，那么hacker就只有在2分钟之内进行破解，增加安全性\n\n\n","什么是socket，iOS中的Socket如何实现，tcp和udp在socket中起到哪些作用，咱们在这里一起探讨一下。","",499668042977349,{"phone":15,"userId":13,"nickName":16,"vipType":17,"avatar":18,"sign":19,"createdAt":20},"13121171998","全栈老韩",1,"https://image.xinwei.ltd/images/IMG_5430.JPG","全栈工程师，擅长iOS App开发、前端（vue、react、nuxt、小程序&Taro）开发、Flutter、React Native、后端（midwayjs、golang、express、koa）开发、docker容器、seo优化等。","2024-01-01T16:14:30.305Z",2,{"id":21,"name":23},"IT技术",3,{"id":24,"name":26,"parentId":21},"iOS",[],33,0,"socket,ios,ios socket,ios tcp,ios udp,ios开发"]