ios客户端访问fastdfs linux服务器遇到的问题

一、基本需求:主要是实现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.主要实现ios客户端能访问服务器,进行文件的上传和下载操作。需要先在Mac上编译fastdfs(不需要安装,将make.sh文件里面引用libfastcommon的地方换成解压后的目录),目前作者提供的版本早已支持在Mac上编译,经过修改make.sh,添加了宏定义等,在Mac上面能编译通过,也能够正常进行下载和上传文件。

       client目录添加make.sh文件,通过脚本去编译,添加的宏定义如下,(脚本其它部分未贴出来,可参考代码里面本身的脚本):


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

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

       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);

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

       4.遇到的主要问题是C语言在ios上的系统调用问题

      在xcode上将编译出来的libfdfsclient.a文件,将其和修改后的上传文件和下载文件的接口(.h头文件)放到xcode里面编译运行,上传文件时报错:

       sendfile系统调用返回-1,加日志具体errno返回78,打印出function not implemented。

       看了下作者在这里有处理,区分了linux系统和FreeBSD系统(darwin),但这里在Mac Pro苹果笔记本上运行没有问题,ios手机上有问题。


       难道是ios系统将这个系统调用的实现砍掉了?即使砍掉了,为什么ios11.2的sdk里面socket.h这个头文件里面还有sendfile这个方法的声明,如果砍掉就将声明一起去掉好了,这点令人费解,

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

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

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

#ifdef OS_FREEBSD
offset = file_offset;
#if defined(DARWIN)
# if defined(IOS) //增加代码开始处
    int BUFFER_SIZE = 1024;
    char buffer[BUFFER_SIZE];
    result = 0;
    FILE *fp = fopen(filename, "r");
    if(NULL == fp)
    {
        printf("File:%s Not Found\n", filename);
        exit(1);
    }
    else
    {
        bzero(buffer, BUFFER_SIZE);
        int length = 0;
        while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
        {
            //printf("length:%d\n", length);
            if(send(sock, buffer, length, 0) < 0)
            {
                printf("Send File:%s Failed\n", filename);
                break;
            }
            bzero(buffer, BUFFER_SIZE);
        }
        fclose(fp);
    } //增加代码结束处
#else

result = 0;
remain_bytes = file_bytes;
    int sendres = -1;
while (remain_bytes > 0)
{
        off_t len;
        len = remain_bytes;
        sendres = sendfile(fd, sock, offset, &len, NULL, 0);
        
        printf("sendfile result sendres:%d\n", sendres);
        if (sendres != 0) {
result = errno != 0 ? errno : EIO;
            printf("result:%d\n", result);
            if (result != EINTR)
            {
                break;
            }
        }
remain_bytes -= len;
    }
#endif
#else
remain_bytes = file_bytes;
    result = 0;
while (remain_bytes > 0)
    {
        off_t sbytes;
        sbytes = 0;
        if (sendfile(fd, sock, offset, remain_bytes, NULL, &sbytes, 0) != 0)
        {
            result = errno != 0 ? errno : EIO;
            if (result != EINTR)
            {
                break;
            }
        }
        remain_bytes -= sbytes;
    }
#endif
#endif

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

//
//  ViewController.m
//  test0321_02
//
//  Created by waj on 2018/3/21.
//  Copyright © 2018年 waj. All rights reserved.
//

#import "ViewController.h"
#import "fdfs_up_download_file.h"
#import <fcntl.h>
#import <errno.h>

@interface ViewController ()

@end

@implementation ViewController

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

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

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

    //下载文件测试
    //    int test = download_file([configFilePath UTF8String], [server_file UTF8String], [filePath UTF8String]);
    //    NSLog(@"test:%d",test);
    
    UIImage *image = [UIImage imageWithContentsOfFile:filePath];
    NSLog(@"==");
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        //处理耗时操作
        char *serverUrl = upload_file([configFilePath UTF8String], [filePath UTF8String]);
        NSLog(@"upload_result:%s", serverUrl);
        
        //通知主线程更新
        dispatch_async(dispatch_get_main_queue(), ^{
           //回调或者通知主线程更新
        });
    });
}

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

2018-03-29 10:54:41.879915+0800 test0329[21422:8431941] cachePath:/var/mobile/Containers/Data/Application/8F3B9EFE-C7C9-4554-8356-F8CDEA8FD368/Library/Caches
[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群,本来想请教下,然而加不上,应该是人员早满了,所以就自己尝试了



    参考:http://bbs.chinaunix.net/forum.php?mod=forumdisplay&fid=240&typeid=428

              http://bbs.chinaunix.net/thread-1920470-1-1.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值