忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 1614 | 回复: 0

[FastDFS] MacBook pro上利用xcode搭建fastdfs环境,编译.a文件,供ios客户端调用 [复制链接]

论坛徽章:
0
发表于 2018-04-02 14:59 |显示全部楼层
本帖最后由 xiaojunfucking 于 2018-04-02 19:06 编辑

需求:主要是实现ios客户端可以访问linux服务器上面配置的fastdfs服务器,能够实现上传和下载文件

作者发布的最新版本代码地址:https://github.com/happyfish100/

fastdfs版本:FastDFS_v5.08.tar.gz,libfastcommon也是最新版本,下载版本时间大约2018.03.01左右

思路:

       1.ios选择用object-c开发的客户端,可以调用C语言程序,具体可百度,网上很多demo,需要增加对应的.h文件(https://blog.csdn.net/hitourlee/article/details/38511435

       2.在Macbook Pro的终端上(相当于Windows的cmd控制台),只编译client里面的fdfs_download_file.c和fdfs_upload_file.c,所有相关依赖加入到Makefile里面,编译出可执行文件,可在终端上成功完成上传和下载。

       但是编译出来的静态包libfdfsclient.a文件,默认是x86_64的,iPhone5以后的cpu架构是需要静态包支持arm64架构的,我未去查怎么修改脚本文件编译出来arm64架构的静态包,而是直接在xcode上将代码导入,修改xcode上的配置(这里可以百度搜一下编译出来arm64静态包,都有资料)

       3.这里对余大侠的代码,稍微修改了下,将main函数里面的控制台参数传入功能封装到函数里面,并配套写对应的.h文件

fdfs_upload_download.h,内容如下:

/*

config_file: client.conf

server_file: like group1/M00/00/83/CgAACFqfm6mAZBvIAAAUABzabag5036295

local_filename: your save file name in local, include file path下载文件将ios客户端要保存的路径包括文件名传入了,ios客户端的文件是沙盒形式,需要客户端自己设置自己的目录(如cache目录),才有权限去写

*/

int download_file(char *conf_filename, char *server_file, char *local_filename);

/*

config_file: client.conf

local_filename: like /home/wb/1.jpg

file_id: return server value, like group1/M00/00/83/CgAACFqfm6mAZBvIAAAUABzabag5036295上传文件成功,直接返回服务器的相对路径

*/

char * upload_file(char *conf_filename, char *local_filename);

xcode里面编译静态库的时候,可以设置宏定义,这样才能满足作者设置的条件编译

这样修改后,能够成功编译出来,ios客户端能够成功下载,但是在文件上传时,可能会遇到问题:

        xcode里面直接跳到sendfile函数那里异常(系统调用sendfile返回-1,errno=78,提示fuction not implmented),如下图(注明:Macbook pro上面运行没有问题,能够正常上传和下载,相应的系统库文件里面也有sendfile函数的声明),但是ios上面运行有问题,难道ios系统将这个系统调用的实现砍掉了?即使砍掉了,为什么ios11.2的sdk里面socket.h这个头文件里面还有sendfile这个方法的声明,如果砍掉就将声明一起去掉好了,这里有点令人费解

解决方法:我利用的最原始发送文件的方法,未去查看其它更好的方法,不用优化后的sendfile函数,如果有更好方法的同学,可以指点下,或者余大侠修改下,提供下技术支持

加了一个宏定义,如果是ios平台,走此条件,其它的依旧走sendfile流程

修改文件:libfastcommon--->src--->sockopt.c--->tcpsendfile_ex函数

  1. #ifdef OS_FREEBSD
  2.     offset = file_offset;
  3. #if defined(DARWIN)
  4. #if defined(IOS)
  5.     int BUFFER_SIZE = 1024;
  6.     char buffer[BUFFER_SIZE];
  7.     result = 0;
  8.     FILE *fp = fopen(filename, "r");
  9.     if(NULL == fp)
  10.     {
  11.         printf("File:%s Not Found\n", filename);
  12.         exit(1);
  13.     }
  14.     else
  15.     {
  16.         bzero(buffer, BUFFER_SIZE);
  17.         int length = 0;
  18.         while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
  19.         {
  20.             //printf("length:%d\n", length);
  21.             if(send(sock, buffer, length, 0) < 0)
  22.             {
  23.                 printf("Send File:%s Failed\n", filename);
  24.                 break;
  25.             }
  26.             bzero(buffer, BUFFER_SIZE);
  27.         }
  28.         fclose(fp);
  29.     }
  30. #else
  31.    
复制代码

至此,编译出来的静态库文件能够被ios客户端正常使用,需要写一个ios demo来测试一下,下面是新建ios demo里面修改的代码,将.a文件和.h文件导入工程

  1. //
  2. //  ViewController.m
  3. //  test0321_02
  4. //
  5. //  Created by waj on 2018/3/21.
  6. //  Copyright © 2018年 waj. All rights reserved.
  7. //

  8. #import "ViewController.h"
  9. #import "fdfs_up_download_file.h"
  10. #import <fcntl.h>
  11. #import <errno.h>

  12. @interface ViewController ()

  13. @end

  14. @implementation ViewController

  15. - (void)viewDidLoad {
  16.     [super viewDidLoad];
  17. // Do any additional setup after loading the view, typically from a nib.
  18.    
  19.     //首先寻找cache里面是否有对应图片
  20.     //获取Caches目录
  21.     NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
  22.     NSLog(@"cachePath:%@\n", cachesPath);

  23.     NSString *filePath = [cachesPath stringByAppendingString:[NSString stringWithFormat:@"/%@",@"1.png"]];
  24.     NSLog(@"filePath:%@\n", filePath);

  25.     //    NSString *server_file = @"group1/M00/00/00/rBADzVpNxKuABlV1AAAimOO322c001.png";
  26.     //    NSLog(@"server_file:%@\n", server_file);
  27.    
  28.     NSString *configFilePath = [self getConfigFilePath];
  29.     NSLog(@"configFilePath:%@\n", configFilePath);

  30.     //下载文件测试
  31.     //    int test = download_file([configFilePath UTF8String], [server_file UTF8String], [filePath UTF8String]);
  32.     //    NSLog(@"test:%d",test);
  33.    
  34.     UIImage *image = [UIImage imageWithContentsOfFile:filePath];
  35.     NSLog(@"==");
  36.     <blockquote>    dispatch_async(dispatch_get_global_queue(0, 0), ^{
复制代码

    4.测试过程中,还有一些问题,还没来的及分析,在某些android手机、ios手机上,fastdfs会报出no route to host的错误,网上大多都说是服务器的防火墙打开了,我这里确定不是这个防火墙的问题,如果是防火墙的问题,所有的客户端访问都会有问题,而不是某些手机有问题。ios手机版本10.3.2和11.2.x的 版本iphone6和iPhone6plus上是正常的,但是一位同事的ios版本11.2.x出现该问题

  1. 2018-03-29 10:54:41.879915+0800 test0329[21422:8431941] cachePath:/var/mobile/Containers/Data/Application/8F3B9EFE-C7C9-4554-8356-F8CDEA8FD368/Library/Caches
  2. [2018-03-29 10:54:41] ERROR - file: /Users/waj/Desktop/Fastdfs-common/libfastcommon-master/src/connection_pool.c, line: 130, connect to 10.0.3.14:22122 fail, errno: 65, error info: No route to host
复制代码

    待进一步去分析,看能不能从某些手机无法建立socket连接去分析,写一个demo测试排除下问题


另:可能已经有兄弟早将ios版本编译出来,成功运行过,也请指点下。看有无更好的方法。

余大侠发的帖子里面有qq群,本来想请教下,然而加不上,应该是人员早满了,所以就自己尝试了


您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:wangnan@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP