• 高级UIKit-09(TCPSocket发送文件、上传和下载)


    【day1101_SocketSendFile】:发送文件到服务端

    发送文件需要在该文件上拼接消息头,比如类型,文件名,文件大小

    // 服务端
    
    - (void)viewDidLoad
    
    {
    
        [super viewDidLoad];
    
        // 创建服务器
    
        self.socketServer = [[AsyncSocket alloc] initWithDelegate:self];
    
        // 设置端口
    
        [self.socketServer acceptOnPort:8000 error:Nil];
    
       
    
    }
    
     
    
    // 接收连接
    
    - (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket{
    
        self.socketNew = newSocket;
    
    }
    
    // 连接成功
    
    - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{
    
        [self.socketNew readDataWithTimeout:-1 tag:0];// 读取数据
    
    }
    
    // 读取数据
    
    - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    
        // 判断是否是头
    
        NSData *headerData = [data subdataWithRange:NSMakeRange(0, 50)];
    
        NSString *headerString = [[NSString alloc] initWithData:headerData encoding:NSUTF8StringEncoding];
    
        if (headerString && [headerString componentsSeparatedByString:@"&&"].count == 3) {
    
            NSArray *fileArray = [headerString componentsSeparatedByString:@"&&"];
    
            NSString *type = fileArray[0];
    
            if ([type isEqualToString:@"file"]) { // 如果是文件
    
                self.fileData = [NSMutableData data];
    
                self.fileName = fileArray[1];
    
                self.fileLength = [fileArray[2] intValue];
    
                NSData *subData = [data subdataWithRange:NSMakeRange(50, data.length - 50)];
    
                [self.fileData appendData:subData];
    
            }else{
    
               
    
            }
    
        }else{
    
            [self.fileData appendData:data];
    
        }
    
        NSLog(@"%d,%d",data.length,self.fileData.length);
    
        // 判断是否接收完成
    
        if (self.fileData.length == self.fileLength) {
    
            NSString *filePath = [@"/Users/tarena/yz/第三阶段(高级UI)/day11" stringByAppendingPathComponent:self.fileName];
    
            [self.fileData writeToFile:filePath atomically:YES];
    
        }
    
        [self.socketNew readDataWithTimeout:-1 tag:0];// 读取数据
    
    }
    
     
    
    //客户端
    
    - (IBAction)clicked:(id)sender {
    
        // 创建客户端
    
        self.socketClient  = [[AsyncSocket alloc] initWithDelegate:self];
    
        // 连接服务器
    
        if ([self.socketClient connectToHost:@"localhost" onPort:8000 error:Nil]) {
    
            NSLog(@"连接成功!");
    
        }
    
        if ([self.sendTextField.text hasPrefix:@"/"]) { // 如果是文件
    
            // 得到文件路径
    
            NSString *filePath = self.sendTextField.text;
    
            // 转成data
    
            NSData *fileData = [NSData dataWithContentsOfFile:filePath];
    
            // 拼接信息头
    
            NSString *headerString = [NSString stringWithFormat:@"file&&%@&&%d",[filePath lastPathComponent],fileData.length];
    
            // 转成data
    
            NSData *headerData = [headerString dataUsingEncoding:NSUTF8StringEncoding];
    
            // 发送数据
    
            NSMutableData *allData = [NSMutableData dataWithLength:50];
    
            [allData replaceBytesInRange:NSMakeRange(0, headerData.length) withBytes:headerData.bytes];
    
            [allData appendData:fileData];
    
            [self.socketClient writeData:allData withTimeout:-1 tag:0];
    
        }else{ // 如果是文本
    
            NSString *headerString = [NSString stringWithFormat:@"text&& &&"];
    
            NSData *fileData = [headerString dataUsingEncoding:NSUTF8StringEncoding];
    
            // 转为data
    
            NSData *headerData = [headerString dataUsingEncoding:NSUTF8StringEncoding];
    
            // 发送
    
            NSMutableData *allData = [NSMutableData dataWithCapacity:50];
    
            [allData replaceBytesInRange:NSMakeRange(0, headerData.length) withBytes:headerData.bytes]; // 替换为消息头
    
            [allData appendData:fileData];
    
            [self.socketClient writeData:allData withTimeout:-1 tag:0];
    
        }
    
       
    
    }

     

    - (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag{

        NSLog(@"发送完成!");

    }

     

    【day1102_uploadAndDown】:上传和下载客户端

    需求:实现上传和下载功能

     分三步完成,先上传,在获取下载列表,最后是下载

    上传文件是通过在文件中拼接消息头完成

    - (void)viewDidLoad
    
    {
    
        [super viewDidLoad];
    
        self.socketClient = [[AsyncSocket alloc] initWithDelegate:self];
    
        [self.socketClient connectToHost:@"192.168.1.188" onPort:8000 withTimeout:-1 error:Nil];
    
        // 发送数据
    
        NSLog(@"发送数据");
    
        NSString *headerString = [NSString stringWithFormat:@"upload&&%@&&%d",self.file.fileName,self.file.fileLength];
    
        NSMutableData *allData = [MXUtils getAllDataByHeaderString:headerString];
    
        NSData *fileData = [NSData dataWithContentsOfFile:self.file.filePath];
    
        NSLog(@"%d",self.file.fileLength);
    
        [allData appendData:fileData];
    
        [self.socketClient writeData:allData withTimeout:-1 tag:0];
    
        self.labelUploadInfo.text = [NSString stringWithFormat:@"上传%@",self.file.fileName];
    
    }
    
     
    
     
    
    -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag{
    
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"上传成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:Nil, nil];
    
        [alert show];
    
    }

     

     

    获取下载列表是通过互相发送消息,从服务端把文件对象(也就是文件在服务端的绝对路径)归档发送到客户端,然后在客户端反归档获取文件列表

    - (void)viewDidLoad
    
    {
    
        [super viewDidLoad];
    
        self.socketClient = [[AsyncSocket alloc] initWithDelegate:self];
    
        [self.socketClient connectToHost:@"192.168.1.188" onPort:8000 withTimeout:-1 error:Nil];
    
        NSString *headerString = @"downList&& &&";
    
        NSMutableData *allData = [MXUtils getAllDataByHeaderString:headerString];
    
        [self.socketClient writeData:allData withTimeout:-1 tag:0];
    
        [self.socketClient readDataWithTimeout:-1 tag:0];
    
     
    
    }
    
     
    
    -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    
        // 反归档
    
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    
        self.filePathArray = [unarchiver decodeObjectForKey:@"downlist"];
    
        NSLog(@"%@",self.filePathArray);
    
        [self.tableView reloadData];
    
    }

    下载是通过列表中的文件路径发送给服务端,然后服务端根据其路径找到文件返回去

    - (void)viewDidLoad
    
    {
    
        [super viewDidLoad];
    
        self.fileData = [NSMutableData data];
    
        self.socketClient = [[AsyncSocket alloc] initWithDelegate:self];
    
        [self.socketClient connectToHost:@"192.168.1.188" onPort:8000 withTimeout:-1 error:Nil];
    
        // 发送数据
    
        NSLog(@"发送数据");
    
        NSString *headerString = [NSString stringWithFormat:@"download&&%@&&",self.file.filePath];
    
        NSMutableData *allData = [MXUtils getAllDataByHeaderString:headerString];
    
        NSLog(@"%d",self.file.fileLength);
    
        [self.socketClient writeData:allData withTimeout:-1 tag:0];
    
        self.labelDownload.text = [NSString stringWithFormat:@"下载%@",self.file.fileName];
    
        [self.socketClient readDataWithTimeout:-1 tag:0];
    
    }
    
     
    
     
    
    -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    
        [self.fileData appendData:data];
    
        if (self.fileData.length == self.file.fileLength) {
    
           
    
            [self.fileData writeToFile:[@"/Users/tarena/yz/第三阶段(高级UI)/day11/download" stringByAppendingPathComponent:self.file.fileName] atomically:YES];
    
           
    
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"下载成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:Nil, nil];
    
            [alert show];
    
        }
    
        [self.socketClient readDataWithTimeout:-1 tag:0];
    
    }

     

    【day1103_UploadAndDownSocketServer】:上传和下载服务端

    - (void)viewDidLoad
    
    {
    
        [super viewDidLoad];
    
       
    
        self.socketServer = [[AsyncSocket alloc] initWithDelegate:self];
    
        [self.socketServer acceptOnPort:8000 error:Nil];
    
       
    
    }
    
     
    
    -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket{
    
        NSLog(@"通道");
    
        self.socketNew = newSocket;
    
    }
    
     
    
    -(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{
    
        NSLog(@"连接成功%@",host);
    
        self.host = host;
    
        [self.socketNew readDataWithTimeout:-1 tag:0];
    
    }
    
     
    
    -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    
        NSLog(@"读取数据成功");
    
        // 判断是否有消息头
    
        NSData *headerData = [data subdataWithRange:NSMakeRange(0, 100)];
    
        NSString *headerString = [[NSString alloc] initWithData:headerData encoding:NSUTF8StringEncoding]; // 消息头
    
        if (headerString && [headerString componentsSeparatedByString:@"&&"].count == 3) {
    
            NSLog(@"有消息头");
    
            NSArray *headerArray = [headerString componentsSeparatedByString:@"&&"];
    
            NSString *type = headerArray[0];
    
            if ([type isEqualToString:@"upload"]) {
    
                self.allData = [NSMutableData data];
    
                self.fileName = headerArray[1];
    
                self.fileLength = [headerArray[2] intValue];
    
                NSData *subData = [data subdataWithRange:NSMakeRange(100, data.length - 100)];
    
                [self.allData appendData:subData];
    
                self.labelUploadInfo.text = [NSString stringWithFormat:@"%@在上传%@文件",self.host,self.fileName];
    
                self.progressUpload.progress = self.allData.length * 1.0 / self.fileLength;
    
            }else if([type isEqualToString:@"downList"]){
    
                NSData *data = [MXUtils getFilePathArrayDataByDirectoryPath:@""];
    
                [self.socketNew writeData:data withTimeout:-1 tag:0];
    
            }else if([type isEqualToString:@"download"]){
    
                NSString *filePath = headerArray[1];
    
                NSData *data = [NSData dataWithContentsOfFile:filePath];
    
                [self.socketNew writeData:data withTimeout:-1 tag:0];
    
            }
    
           
    
        }else{
    
            [self.allData appendData:data];
    
            self.progressUpload.progress = self.allData.length * 1.0 / self.fileLength;
    
        }
    
        if (self.allData.length == self.fileLength) {
    
            NSString *path = [@"" stringByAppendingPathComponent:self.fileName];
    
            NSLog(@"写到%@",path);
    
            [self.allData writeToFile:path atomically:YES];
    
        }
    
        [self.socketNew readDataWithTimeout:-1 tag:0];
    
    }

     把消息头存进要发送的数据中 并且固定占用多少字节

     

    使用网络需要导入CFNetwork.framework框架

     

  • 相关阅读:
    程序数据校验
    修改文件名后,pip命令报错:Fatal error in launcher: Unable to create process using
    算法竞赛平台
    连续子数组的元素之和最大值
    【数学计算】圆周率
    使用DOS命令关闭tomcat端口(其他服务也是可以的)
    微软project文件mpp解析
    关于读取上传文件问题的两个解决办法
    关于office在卸载了某一应用之后无法试图使用的功能所在的网络位置
    关于eclipse的一些问题
  • 原文地址:https://www.cnblogs.com/yangmx/p/3561304.html
Copyright © 2020-2023  润新知