您的位置:首页 > 理论基础 > 计算机网络

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

2016-08-01 13:28 375 查看
最近在学习网络编程,发现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连接,客户端仍然在接收。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息