Workerman实现文件上传

2018-06-01  本文已影响0人  黑小马_

谈到文件上传,就需要看workerman的文档,文档资料比较丰富,但是我觉得还是有些问题,比如PHP的Pack函数,到现在我也不知道怎么用其他语言去写,这个问题能也不能归结到PhP上,只能怪自己能力不行!,贴出Java版的Pack函数,但是我也没搞懂这个Pack

image

还有就是关于网络字节序的unsigned int数据,怎么用java发,确实不知道怎么搞!最后的办法就是通过Base64来发送文件,可以完美解决跨语言发文件,因为本人最热爱,java,php,

第一步,看文档,了解Workerman的如何自定义协议,根据文档介绍,自己创建一个php 类文件文件

必须要包含三个静态方法

image image image

然后分别定义一个命名空间

image

该文件放在

image

最后你就可以用了

贴出该文件的全部代码

/**

* Created by PhpStorm.

* User: hxm

* Date: 2018/6/1

* Time: 10:15

*/

namespace Workerman\Protocols;

/*

* {"file_name":"logo.png","file_data":"PD9waHAKLyo......"}\n

* 协议定义,这个\n,必须包含,标识一个完整的数据包结束*/

class File_protocol{

    /*

    * 检查包完整性    * 返回包的整体长度;    * 返回0,等带下次上传    * 返回false,断开客服端的连接*

*/

    public static function input($rec_buff){

    //  echo $rec_buff;

        $recv_len = strlen($rec_buff);

        if($rec_buff[$recv_len-1] !=="\n")

{

            return 0;

        }

        return strlen($rec_buff);

    }

    /*

    * 解包数据,该数据,并返回    * 该方法,返回后再worker实例的onMessage方法调用!*

*/

    public static function decode($rec_buff){

        // 解包

        $package_data = json_decode(trim($rec_buff), true);

        // 取出文件名

        $file_name = $package_data['file_name'];

        // 取出base64_encode后的文件数据

        $file_data = $package_data['file_data'];

        $file_data = base64_decode($file_data);

        // 返回数据

        return array(

            'file_name' => $file_name,

            'file_data' => $file_data,

        );

    }

    /*

    * 打包,当向客户端发送数据的时候会自动调用*

*/

    public static function encode($rec_buff){

        // 可以根据自己的需要编码发送给客户端的数据,这里只是当做文本原样返回

        return $rec_buff;

    }

}

最后你就可以这自己写一个文件运行了

image image

接下分别采用Java和Php客服端做例子

import sun.misc.BASE64Encoder;

import java.io.*;

import java.net.Socket;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public class Test {

public static void main(String[] args)throws Exception {

Socket socket =new Socket("127.0.0.1", 8888);

        //获取输出流

        OutputStream out = socket.getOutputStream();

        //文件编码

        String s =encodeBase64File("F:\\a.rar");

        //去除特殊符号

        String s1 =replaceBlank(s);

        //构建数据包

        String pack ="{\"file_name\":\"logo.rar\",\"file_data\":\"" + s1 +"\"}\n";

        out.write(pack.getBytes("UTF-8"));

        out.flush();

        out.close();

        socket.close(); // 关闭Socket

    }

/**

    * @Author: 黑小马

    * @Date: 2018/6/1

    * @Description:出除字符串的\t\r\n

    **/

    public static StringreplaceBlank(String str) {

String dest ="";

        if (str !=null) {

Pattern p = Pattern.compile("\\s*|\t|\r|\n");

            Matcher m = p.matcher(str);

            dest = m.replaceAll("");

        }

return dest;

    }

/**

    * @Author: 黑小马

    * @Date: 2018/6/1

    * @Description:进行文件编码

    **/

    public static StringencodeBase64File(String path)throws Exception {

File file =new File(path);

        FileInputStream inputFile =new FileInputStream(file);

        byte[] buffer =new byte[(int) file.length()];

        inputFile.read(buffer);

        inputFile.close();

        return new BASE64Encoder().encode(buffer);

    }

public static byte[]pack(String str) {

int nibbleshift =4;

        int position =0;

        int len = str.length() /2 + str.length() %2;

        byte[] output =new byte[len];

        for (char v : str.toCharArray()) {

byte n = (byte) v;

            if (n >='0' && n <='9') {

n -='0';

            }else if (n >='A' && n <='F') {

n -= ('A' -10);

            }else if (n >='a' && n <='f') {

n -= ('a' -10);

            }else {

continue;

            }

output[position] |= (n << nibbleshift);

            if (nibbleshift ==0) {

position++;

            }

nibbleshift = (nibbleshift +4) &7;

        }

return output;

    }

}

php客服端

<?php
/** 上传文件客户端 **/
// 上传地址
$address = "127.0.0.1:8888";
// 检查上传文件路径参数
if(!isset($argv[1]))
{
   exit("use php client.php \$file_path\n");
}
// 上传文件路径
$file_to_transfer = trim($argv[1]);
// 上传的文件本地不存在
if(!is_file($file_to_transfer))
{
    exit("$file_to_transfer not exist\n");
}
// 建立socket连接
$client = stream_socket_client($address, $errno, $errmsg);
if(!$client)
{
    exit("$errmsg\n");
}
stream_set_blocking($client, 1);
// 文件名
$file_name = basename($file_to_transfer);
// 文件二进制数据
$file_data = file_get_contents($file_to_transfer);
// base64编码
$file_data = base64_encode($file_data);

echo $file_data;
// 数据包
$package_data = array(
    'file_name' => $file_name,
    'file_data' => $file_data,
);
// 协议包 json+回车
$package = json_encode($package_data)."\n";
// 执行上传
fwrite($client, $package);
// 打印结果
echo fread($client, 8192),"\n";

以上基本 都是帖代码,但是整体思路是完全没有问题,更多的就是去看手册!
或者我应该去看看那个pack方式,baes64,编码后的整体会比源文件大一些,感觉不是很好!

上一篇下一篇

猜你喜欢

热点阅读