美文网首页
Workerman实现文件上传

Workerman实现文件上传

作者: 黑小马_ | 来源:发表于2018-06-01 11:50 被阅读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,编码后的整体会比源文件大一些,感觉不是很好!

    相关文章

      网友评论

          本文标题:Workerman实现文件上传

          本文链接:https://www.haomeiwen.com/subject/amwhsftx.html