ios中利用BSDSocket进行网络通信(客户端篇)

来源:互联网 发布:手机充电加速软件 编辑:程序博客网 时间:2024/06/04 05:50

最近在学习网络编程,发现BSDSocket进行网络通信是一件比较有趣的事情,顺便记下笔记

详情如下:

- (void)createSocketClientWithURL:(NSURL*)url{
    // int socket(int addressFamily, int type, int protocol)
    // addressFamily:IP协议类型 AF_INET指IPV4
    // type:socket的类型,一般为字节流stream(SOCK_STREAM) 或 数据报文datagram(SOCK_DGRAM)
    // protocol:协议,一般填0,让OS自动选取最佳协议
    // 函数返回socket的文件描述符
    int socketDecriputor = socket(AF_INET, SOCK_STREAM, 0);
    if (socketDecriputor == -1) {
        NSLog(@"socket创建失败");
    }
    
    //通过服务器的域名得到服务器的ip地址
    NSString* hostName = [url host];
    NSNumber* port = [url port];
    struct hostent* remoteHostEnt = gethostbyname(hostName.UTF8String);
    struct in_addr* remoteInAdd = (struct in_addr*)remoteHostEnt->h_addr_list[0];
    
    //sockaddr_in 保存要连接的服务器的相关信息
    struct sockaddr_in addParamters;
    addParamters.sin_family = AF_INET;
    addParamters.sin_addr = *remoteInAdd;
    //htons是将整型变量从主机字节顺序转变成网络字节顺序, 就是整数在地址空间存储方式变为:高位字节存放在内存的低地址处
    addParamters.sin_port = htons([port intValue]);
    
    // int connect(int socketFileDescriptor, sockaddr *serverAddress, int serverAddressLength)
    // socketFileDescriptor: socket 的文件描述符
    // serverAddress:服务器地址
    // serverAddressLength:服务器地址长度
    // 连接成功返回0,失败返回 -1
    int reslut = connect(socketDecriputor, (struct sockaddr *)&addParamters, sizeof(addParamters));
    if (reslut == -1) {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.resultStr.text = @"连接服务器失败";
        }];
        return;
    }else{
        //用于保存从网络中接收的信息
        NSMutableData* data = [NSMutableData data];
        BOOL waitingForData = YES;
        
        while (waitingForData) {
            const char* buffer[1024]; //数据缓存区
            long len = sizeof(buffer);
            long resutlLen = recv(socketDecriputor, &buffer, len, 0);
            if (resutlLen == -1) {
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                    self.resultStr.text = @"接收失败";
                }];
                return;
            }
            [data appendBytes:&buffer length:resutlLen];
            
            
            if (resutlLen == 0) {
                waitingForData = NO;
            }
        }
        close(socketDecriputor);
        
        NSString* resultStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        //    UIImage* image = [UIImage imageWithData:data];
        //回到主线程刷新页面
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.resultStr.text = resultStr;
            //        self.imaV.image = image;
        }];

    }
}

注意的是,当recv函数返回值为0时,一般是对端关闭了socke连接,客户端仍然在接收。

1 0
原创粉丝点击