Beispiel #1
0
        private DynObject Transfer(ushort serverPort, byte[] buffer, int count)
        {
            //发送数据
            Send(serverPort, buffer);

            ZmqMessage message = _ftpSocket.ReceiveMessage(new TimeSpan(0, 1, 30));

            if (message.FrameCount == 0)
            {
                _isWorking = false;
                ReStart();
                throw new TimeoutException("发送超时,请检查你的网络是否有问题,稍后重新上传");
            }
            else
            {
                //反序列化,取出服务端响应数据
                byte[]      respData   = message[message.FrameCount - 1].Buffer;
                TSerializer serializer = new TBinarySerializer();
                serializer.FromBytes(respData);
                DynObject fileFragment = DynSerialize.ReadDynObject(serializer);
                serializer.Flush();

                //105:发生异常
                if ((byte)fileFragment["State"] == 105)
                {
                    _isWorking = false;
                    throw new ApplicationException(fileFragment["ExcepMsg"] as string);
                }

                return(fileFragment);
            }
        }
        /// <summary>
        /// 处理返回消息
        /// </summary>
        /// <param name="msgData">返回消息</param>
        private object DealRepMessage(byte[] msgData)
        {
            TSerializer serializerResp = new TBinarySerializer();

            serializerResp.FromBytes(msgData);
            TMessage respMsg = serializerResp.ReadMessageBegin();

            if (respMsg.Type == TMessageType.Exception)
            {
                this.RaiseDealMessageExceptionEvent(TApplicationException.Read(serializerResp));

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                return(null);;
            }

            if (respMsg.Type != TMessageType.RpcReply)
            {
                this.RaiseDealMessageExceptionEvent(new ApplicationException("非法的返回类型:" + respMsg.Type.ToString()));

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                return(null);
            }

            string[]          temp = respMsg.Name.Split('_');
            DynMethodInstance dynMethodInstance = new DynMethodInstance(temp[0], temp[1]);

            try
            {
                dynMethodInstance.Result = DynSerialize.ReadResult(serializerResp, dynMethodInstance);
            }
            catch (Exception ex)
            {
                this.RaiseDealMessageExceptionEvent(ex);

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();
            }

            // 消息结束
            serializerResp.ReadMessageEnd();
            serializerResp.Flush();
            return(dynMethodInstance.Result);
        }
Beispiel #3
0
        /// <summary>
        /// 向服务端发送下载文件的请求
        /// </summary>
        /// <param name="destVPort">目的端口</param>
        /// <param name="downloadPath">要下载的文件在服务端的路径</param>
        /// <returns>将要下载文件的基本信息</returns>
        private DynObject RequestDownload(ushort destVPort, string downloadPath)
        {
            DynObject fileFragment = new DynObject("FileFragment");

            fileFragment["Path"]       = Path.GetDirectoryName(downloadPath);
            fileFragment["FileName"]   = Path.GetFileName(downloadPath);
            fileFragment["Extension"]  = Path.GetExtension(downloadPath);
            fileFragment["State"]      = (byte)100;
            fileFragment["MsgID"]      = -1;
            fileFragment["DataLength"] = 0;
            fileFragment["Data"]       = null;

            //序列化要发送的数据
            TSerializer serializer = new TBinarySerializer();

            DynSerialize.WriteDynObject(serializer, fileFragment);
            byte[] buffer = serializer.ToBytes();
            serializer.Flush();

            Send(_serverPort, buffer);
            ZmqMessage msg = _ftpSocket.ReceiveMessage(new TimeSpan(0, 1, 30));

            if (msg.FrameCount == 0)
            {
                _isWorking = false;
                ReStart();
                throw new TimeoutException("发送超时,请检查你的网络是否有问题,稍后重新下载");
            }

            //反序列化,服务器返回的数据
            serializer = new TBinarySerializer();
            serializer.FromBytes(msg[msg.FrameCount - 1].Buffer);
            DynObject respFragment = DynSerialize.ReadDynObject(serializer);

            serializer.Flush();

            //发生异常
            if ((byte)respFragment["State"] == 105)
            {
                _isWorking = false;
                throw new FtpException(respFragment["ExcepMsg"] as string);
            }

            return(respFragment);
        }
Beispiel #4
0
            /// <summary>
            /// 处理接收到的数据
            /// </summary>
            /// <param name="msgData">接收到的消息</param>
            private byte[] DealMessage(byte[] msgData)
            {
                //反序列化,取出数据
                TSerializer serializer = new TBinarySerializer();

                serializer.FromBytes(msgData);
                DynObject reqFragment = DynSerialize.ReadDynObject(serializer);

                serializer.Flush();

                try
                {
                    DynObject repFragment = OnFileDataReceived(reqFragment);

                    //序列化并把数据返回给客户端
                    serializer = new TBinarySerializer();
                    DynSerialize.WriteDynObject(serializer, repFragment);
                    byte[] repData = serializer.ToBytes();
                    serializer.Flush();

                    return(repData);
                }
                catch (Exception ex)
                {
                    //如果服务端需要记录日志,则由本事件把异常信息发出
                    if (OnException != null)
                    {
                        OnException(ex);
                    }

                    _isRunning = false;

                    DynObject repFragment = new DynObject("FileFragment");
                    repFragment["State"]    = (byte)105;
                    repFragment["ExcepMsg"] = "FtpServer端异常," + ex.Message;

                    //序列化并把异常数据返回给客户端
                    serializer = new TBinarySerializer();
                    DynSerialize.WriteDynObject(serializer, repFragment);
                    byte[] repData = serializer.ToBytes();
                    serializer.Flush();

                    return(repData);
                }
            }
Beispiel #5
0
        /// <summary>
        /// 处理返回消息
        /// </summary>
        /// <param name="msgData">返回消息</param>
        private object DealRepMessage(byte[] msgData, string msgID, out bool isReceive)
        {
            //初始化序列化容器
            TSerializer serializerResp = new TBinarySerializer();

            //将数据读入序列化容器
            serializerResp.FromBytes(msgData);
            //从序列化容器中读取消息
            TMessage respMsg = serializerResp.ReadMessageBegin();

            //如果消息的id不对返回空值
            if (msgID != respMsg.MsgID)
            {
                //空方法
                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                isReceive = false;
                return(null);
            }

            //如果是异常消息
            if (respMsg.Type == TMessageType.Exception)
            {
                TApplicationException appException = TApplicationException.Read(serializerResp);
                this.RaiseDealMessageExceptionEvent(appException);

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                throw appException;
            }
            //如果消息是远程调用回应
            if (respMsg.Type != TMessageType.RpcReply)
            {
                this.RaiseDealMessageExceptionEvent(new ApplicationException("非法的返回类型:" + respMsg.Type.ToString()));

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                isReceive = true;
                return(null);
            }

            //构造方法的实例
            string[]          temp = respMsg.Name.Split('_');
            DynMethodInstance dynMethodInstance = new DynMethodInstance(temp[0], temp[1]);

            try
            {
                dynMethodInstance.Result = DynSerialize.ReadResult(serializerResp, dynMethodInstance);
            }
            catch (Exception ex)
            {
                this.RaiseDealMessageExceptionEvent(ex);

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();
            }

            // 消息结束
            serializerResp.ReadMessageEnd();
            serializerResp.Flush();

            isReceive = true;
            return(dynMethodInstance.Result);
        }
Beispiel #6
0
        /// <summary>
        /// 文件下载
        /// </summary>
        /// <param name="recvAddress">服务端机器的地址</param>
        /// <param name="savePath">文件在本地的保存路径</param>
        /// <param name="downloadPath">要下载的文件在服务端的路径</param>
        public void FileDownload(string recvAddress, string savePath, string downloadPath)
        {
            #region 前置检查
            if (_isWorking)
            {
                throw new FtpException("一个FtpClient不能同时执行多个任务");
            }

            //验证本地是否已有同名文件
            if (File.Exists(Path.Combine(savePath, Path.GetFileName(downloadPath))))
            {
                throw new FtpException(savePath + "目录中已存在同名文件");
            }
            #endregion 前置检查

            #region 获取文件的基本信息
            _remoteAddress = new VirtuaIP(recvAddress);
            _serverPort    = GetServerPort("FileDownload");
            _isWorking     = true;

            //发送下载文件的请求
            long      fileSize     = 0; //文件大小(字节)
            long      remaining    = 0; //剩余未下载的文件大小
            DynObject fileFragment = RequestDownload(_serverPort, downloadPath);
            fileSize = remaining = (long)fileFragment["FileLength"];

            #endregion 获取文件的基本信息

            FileStream writeFileStream = null;
            _isCancelDownload = false;

            while (remaining >= 0 && _isWorking)
            {
                if (_isCancelDownload)
                {
                    fileFragment["State"] = (byte)103;
                }

                switch ((byte)fileFragment["State"])
                {
                case 100:
                    string tempFile = Path.Combine(savePath, fileFragment["MD5"] + ".temp");

                    //如果存在该文件的临时文件,则进行断点续传,否则以MD5为名字创建临时文件开始传送数据
                    if (File.Exists(tempFile))
                    {
                        writeFileStream       = new FileStream(tempFile, FileMode.Open);
                        fileFragment["MsgID"] = (int)(writeFileStream.Length / _bufferLength);
                        fileFragment["State"] = (byte)101;
                        fileFragment["Data"]  = null;
                    }
                    else
                    {
                        writeFileStream       = new FileStream(tempFile, FileMode.Create);
                        fileFragment["MsgID"] = 0;
                        fileFragment["State"] = (byte)101;
                        fileFragment["Data"]  = null;
                    }
                    remaining = fileSize - (int)fileFragment["MsgID"] * _bufferLength;
                    break;

                case 101:     //文件传送中
                    writeFileStream.Seek((int)fileFragment["MsgID"] * _bufferLength, SeekOrigin.Begin);
                    writeFileStream.Write(fileFragment["Data"] as byte[], 0, (int)fileFragment["DataLength"]);

                    remaining = fileSize - ((int)fileFragment["MsgID"] * _bufferLength + (int)fileFragment["DataLength"]);
                    if (remaining <= 0)
                    {
                        //文件下载结束
                        fileFragment["State"] = (byte)102;

                        writeFileStream.Flush();
                        writeFileStream.Close();
                        writeFileStream = null;
                        _isWorking      = false;

                        //校验文件传送是否正确
                        string path        = Path.Combine(savePath, fileFragment["MD5"] as string + ".temp");
                        string tempFileMD5 = GetMD5HashFromFile(path);

                        if (tempFileMD5 == fileFragment["MD5"] as string)
                        {
                            File.Move(path, Path.Combine(savePath, fileFragment["FileName"] as string));
                        }
                        else
                        {
                            File.Delete(path);
                            throw new FtpException("文件未能成功下载");
                        }
                    }

                    fileFragment["MsgID"]      = (int)fileFragment["MsgID"] + 1;
                    fileFragment["DataLength"] = 0;
                    fileFragment["Data"]       = null;
                    break;

                case 103:     //中断文件传送
                    fileFragment["DataLength"] = 0;
                    fileFragment["Data"]       = null;

                    writeFileStream.Flush();
                    writeFileStream.Close();
                    writeFileStream = null;
                    _isWorking      = false;
                    break;

                case 105:     //服务端发生异常
                    writeFileStream.Flush();
                    writeFileStream.Close();
                    writeFileStream = null;
                    _isWorking      = false;
                    throw new FtpException(fileFragment["ExcepMsg"] as string);
                }

                //向外界通知文件床送进度
                if (ProgressEvent != null)
                {
                    ProgressEvent(fileSize, fileSize - remaining);
                }

                //发送请求下一个包数据(发生异常告诉对方关闭文件流)
                TSerializer serialize = new TBinarySerializer();
                DynSerialize.WriteDynObject(serialize, fileFragment);
                byte[] buffer = serialize.ToBytes();
                serialize.Flush();

                Send(_serverPort, buffer);
                ZmqMessage message = _ftpSocket.ReceiveMessage(new TimeSpan(0, 1, 30));
                if (message.FrameCount == 0)
                {
                    writeFileStream.Close();
                    writeFileStream = null;
                    _isWorking      = false;
                    ReStart();
                    throw new TimeoutException("发送超时,请检查你的网络是否有问题,稍后重新下载");
                }

                serialize = new TBinarySerializer();
                serialize.FromBytes(message[message.FrameCount - 1].Buffer);
                fileFragment = DynSerialize.ReadDynObject(serialize);
                serialize.Flush();
            }
        }
Beispiel #7
0
        /// <summary>
        /// 重载父类方法
        /// </summary>
        /// <param name="msgData">接收到的消息</param>
        private void DealMessage(object obj)
        {
            ZmqMessage zmqMessage = obj as ZmqMessage;
            //记录源地址和端口
            VirtuaIP originVIP  = new VirtuaIP(zmqMessage[1].Buffer);
            ushort   originPort = (ushort)BitConverter.ToInt16(zmqMessage[3].Buffer, 0);

            byte[] requestData = zmqMessage[zmqMessage.FrameCount - 1].Buffer;

            if (requestData != null && requestData.Length >= 4)
            {
                TSerializer serializer = new TBinarySerializer();
                serializer.FromBytes(requestData);

                // 获取消息
                TMessage msg = serializer.ReadMessageBegin();

                if (msg.Type == TMessageType.RpcCall || msg.Type == TMessageType.RpcOneway)
                {
                    //获取方法信息构造Method
                    string[]          temp           = msg.Name.Split('_');
                    DynMethodInstance methodInstance = null;
                    try
                    {
                        methodInstance = DynSerialize.ReadDynMethodInstance(serializer, temp[0], temp[1]);
                        serializer.ReadMessageEnd();
                        serializer.Flush();

                        Dictionary <string, object> paramValues = new Dictionary <string, object>();
                        //获取参数信
                        foreach (string paramName in methodInstance.DynMethod.GetParameterNames())
                        {
                            paramValues[paramName] = methodInstance[paramName];
                        }

                        string className      = InterfaceImplementMap.InterfaceAndImplementMap[temp[0]];
                        string methodFullName = className + "_" + temp[1];
                        //方法调用
                        object ret = DynTypeManager.MethodHandler(null, methodFullName, paramValues);

                        if (methodInstance.DynMethod.Result.DynType != DynType.Void)
                        {
                            methodInstance.Result = ret;
                        }

                        // 序列化返回结果
                        serializer = new TBinarySerializer();
                        TMessage respMsg = new TMessage(msg.Name, TMessageType.RpcReply, msg.MsgID, msg.LiveLife, "", "", "", "");
                        serializer.WriteMessageBegin(respMsg);
                        DynSerialize.WriteResult(serializer, methodInstance);
                        serializer.WriteMessageEnd();
                        byte[] respData = serializer.ToBytes();
                        serializer.Flush();

                        // 返回客户端
                        Send(originVIP, originPort, respData);
                    }
                    catch (Exception ex)
                    {
                        serializer.ReadMessageEnd();
                        serializer.Flush();

                        //如果服务端需要记录日志,则由本事件把异常信息发出
                        RaiseDealMessageExceptionEvent(ex);

                        byte[] returnData = ReturnExceptionToClient("RpcServer.DealMessageException", msg, ex.Message);
                        // 返回客户端
                        Send(originVIP, originPort, returnData);
                        return;
                    }
                }
            }
        }