public RockRouter(ushort router, ushort port) { _localVIP = new VirtuaIP() { Router = router, Node = uint.MaxValue }; //绑定本地地址 _routerHost = "tcp://*:" + port.ToString(); }
internal RockWorker(VirtuaIP localVIP, string remoteAddress) { _localVIP = localVIP; _nextVIP = new VirtuaIP() { Router = localVIP.Router, Node = uint.MaxValue //运算后节点所能取得最大数:16777215 }; _context = ZmqContext.Create(); _remoteAddress = remoteAddress; }
private void Received() { using (ZmqSocket clientSocket = _context.CreateSocket(SocketType.REP)) { clientSocket.Identity = BitConverter.GetBytes(_localPort); clientSocket.SendHighWatermark = 10000; bool isConnected = false; while (!isConnected) { try { clientSocket.Connect(_inprocHost); isConnected = true; } catch { Thread.Sleep(500); } } try { while (_isRunning) { ZmqMessage zmqMessage = clientSocket.ReceiveMessage(new TimeSpan(0, 2, 0)); if (zmqMessage.FrameCount == 0) { //一分钟内没有收到任何消息,自行关闭 _isRunning = false; continue; } VirtuaIP originVIP = new VirtuaIP(zmqMessage[0].Buffer); ushort originPort = (ushort)BitConverter.ToInt16(zmqMessage[2].Buffer, 0); byte[] respMsg = DealMessage(zmqMessage[zmqMessage.FrameCount - 1].Buffer); //向客户端返回数据 clientSocket.SendMore(originVIP.ToBytes()); clientSocket.SendMore(BitConverter.GetBytes(originPort)); clientSocket.SendMore(BitConverter.GetBytes(_localPort)); clientSocket.Send(respMsg); } } catch (ThreadInterruptedException) { } } //自行关闭释放资源 Dispose(false); }
private void Send(VirtuaIP destVIP, ushort destPort, byte[] data) { /* * 发送数据--共三帧 * 0、空帧 * 1、目的地址 * 2、目的端口 * 3、源端口 * 4、数据 * */ _sendDealer.SendMore(_emptyFrame); _sendDealer.SendMore(destVIP.ToBytes()); _sendDealer.SendMore(BitConverter.GetBytes(destPort)); _sendDealer.SendMore(BitConverter.GetBytes(_receiverVPort)); _sendDealer.Send(data); }
public static RockWorker CreateRockWorker(ushort router, uint node, string remoteAddress) { _localVIP = new VirtuaIP() { Router = router, Node = node, }; //加载通信所需DynClass DynClassLoader.LoadDynClass(); if (_worker != null) { throw new ApplicationException("RockWorker已经创建完成,不需要再次创建"); } _worker = new RockWorker(_localVIP, remoteAddress); _worker.Start(); return(_worker); }
private void Send(VirtuaIP receiverVIP, ushort destVPort, byte[] reqData) { if (_reqSocket == null) { throw new ApplicationException("请你先启动RpcClient"); } /* * 发送数据--共三帧 * 1、目的地址 * 2、目的端口 * 3、源端口 * 4、数据 * */ _reqSocket.SendMore(_emptyFrame); _reqSocket.SendMore(receiverVIP.ToBytes()); _reqSocket.SendMore(BitConverter.GetBytes(destVPort)); _reqSocket.SendMore(BitConverter.GetBytes(_localPort)); _reqSocket.Send(reqData); }
//destVIP 为接收消息的originVIP destPort为接收消息的originPort private void Send(VirtuaIP destVIP, ushort destPort, byte[] data) { //轮流使用队列中的socket(初始化时是300个) ZmqSocket sendSocket = _socketQueue.Dequeue() as ZmqSocket; /* * 发送数据--共三帧 * 0、空帧 * 1、目的地址 * 2、目的端口 * 3、源端口 * 4、数据 * */ sendSocket.SendMore(_emptyFrame); sendSocket.SendMore(destVIP.ToBytes()); sendSocket.SendMore(BitConverter.GetBytes(destPort)); sendSocket.SendMore(BitConverter.GetBytes(_localPort)); sendSocket.Send(data); _socketQueue.Enqueue(sendSocket); }
/// <summary> /// 处理接受数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void ReceiveReady(object sender, SocketEventArgs e) { ZmqSocket socket = e.Socket; ZmqMessage zmqMessage = socket.ReceiveMessage(); /* * 接收数据--共三帧 * 1、源地址(发送数据的地址 路由号.节点号) * 2、端口 * 3、数据 * 这里的接收数据是和发送数据相一致的见上面的Send方法 */ VirtuaIP originVIP = new VirtuaIP(zmqMessage[1].Buffer); ushort originPort = (ushort)BitConverter.ToInt16(zmqMessage[3].Buffer, 0); object resultMsg = DealRepMessage(zmqMessage[4].Buffer); if (OnDataReceived != null) { OnDataReceived(resultMsg); } }
/// <summary> /// 远程方法调用 /// </summary> /// <param name="recvAddress">接收节点的虚拟IP地址,如3.1/param> /// <param name="interfaceName">接口名称</param> /// <param name="methodName">方法名称</param> /// <param name="paramDict">参数字段</param> /// <param name="messageType">消息类型</param> public void Call(string recvAddress, ushort destVPort, string interfaceName, string methodName, Dictionary <string, object> paramDict, TMessageType messageType = TMessageType.RpcCall) { try { VirtuaIP receiverVIP = new VirtuaIP(recvAddress); string msgID = Guid.NewGuid().ToString(); if (!InterfaceImplementMap.InterfaceAndImplementMap.ContainsKey(interfaceName)) { throw new ApplicationException("找不到接口" + interfaceName + "的具体实现!!"); } //本地应用端口随机获取,目标端口确定 TMessage reqMsg = new TMessage(interfaceName + "_" + methodName, messageType, msgID, -1, "", "", "", ""); DynMethodInstance dynMethodInstance = new DynMethodInstance(interfaceName, methodName); TSerializer serializerReq = new TBinarySerializer(); serializerReq.WriteMessageBegin(reqMsg); foreach (var para in paramDict) { dynMethodInstance[para.Key] = para.Value; } DynSerialize.WriteDynMethodInstance(serializerReq, dynMethodInstance); serializerReq.WriteMessageEnd(); byte[] reqData = serializerReq.ToBytes(); serializerReq.Flush(); Send(receiverVIP, destVPort, reqData); } catch (Exception ex) { this.RaiseDealMessageExceptionEvent(ex); throw new ApplicationException(ex.Message); } }
/// <summary> /// 远程方法调用 /// </summary> /// <param name="recvAddress">接收节点的虚拟IP地址,如3.1/param> /// <param name="interfaceName">接口名称</param> /// <param name="methodName">方法名称</param> /// <param name="paramDict">参数字段</param> /// <param name="liveLife">生命周期,以秒为单位</param> /// <param name="messageType">消息类型</param> /// <returns>服务端返回的数据或者null</returns> public object Call(string recvAddress, ushort destVPort, string interfaceName, string methodName, Dictionary <string, object> paramDict, short liveLife, TMessageType messageType = TMessageType.RpcCall) { object result = null; _msgID = _msgID < int.MaxValue ? ++_msgID : 0; try { VirtuaIP receiverVIP = new VirtuaIP(recvAddress); string msgID = _msgID.ToString(); if (!InterfaceImplementMap.InterfaceAndImplementMap.ContainsKey(interfaceName)) { throw new ApplicationException("找不到接口" + interfaceName + "的具体实现!"); } DynMethodInstance dynMethodInstance = new DynMethodInstance(interfaceName, methodName); TMessage reqMsg = new TMessage(interfaceName + "_" + methodName, messageType, msgID, liveLife, "", "", "", ""); TSerializer serializerReq = new TBinarySerializer(); //将消息头信息写入流 serializerReq.WriteMessageBegin(reqMsg); foreach (var para in paramDict) { dynMethodInstance[para.Key] = para.Value; } //将方法的实例写入流 DynSerialize.WriteDynMethodInstance(serializerReq, dynMethodInstance); //什么都不做 serializerReq.WriteMessageEnd(); //将消息流转换成二进制流 byte[] reqData = serializerReq.ToBytes(); serializerReq.Flush(); //发送消息 Send(receiverVIP, destVPort, reqData); var timeout = new TimeSpan(0, 0, liveLife); //创建一个 Stopwatch 实例:使用 StartNew() 会创建一个 Stopwatch 实例并马上开始计时,即等效于如下代码: //Stopwatch sw2 = new Stopwatch(); //sw2.Start(); var timer = Stopwatch.StartNew(); bool isReceive = false; do { ZmqMessage zmqMessage = _reqSocket.ReceiveMessage(timeout - timer.Elapsed); if (zmqMessage.FrameCount == 0) { throw new TimeoutException("调用超时,请检查网络是否联通!"); } else { //zmqMessage[zmqMessage.FrameCount - 1].Buffer 只需要处理zmqMessage中最后一帧,这一帧存的是消息中的数据部分 result = DealRepMessage(zmqMessage[zmqMessage.FrameCount - 1].Buffer, msgID, out isReceive); //消息ID不匹配且超时时间未到时,丢掉当前接收到的数据包,继续接受数据 if (isReceive) { return(result); } } }while (timer.Elapsed <= timeout); throw new TimeoutException("调用超时,请检查网络是否联通!"); } catch (Exception ex) { this.RaiseDealMessageExceptionEvent(ex); throw; } }
/// <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(); } }
/// <summary> /// 文件上传 /// </summary> /// <param name="recvAddress">服务端机器的地址</param> /// <param name="filePath">准备上传的文件</param> /// <param name="savePath">文件在服务端的保存路径</param> public void FileUpload(string recvAddress, string filePath, string savePath) { if (_isWorking) { throw new FtpException("一个FtpClient不能同时执行多个任务"); } CheckPostfix(filePath);//检查上传的文件类型是否合法 string md5 = GetMD5HashFromFile(filePath); _remoteAddress = new VirtuaIP(recvAddress); _serverPort = GetServerPort("FileUpload"); using (FileStream fStream = File.OpenRead(filePath)) { long fileSize = fStream.Length; //文件数据长度 long remaining = fileSize; // 剩余没上传的数据长度 byte[] buffer = new byte[_bufferLength]; //构建文件片段 DynObject fileFragment = new DynObject("FileFragment"); fileFragment["MD5"] = md5; fileFragment["FileName"] = Path.GetFileName(filePath); fileFragment["Extension"] = Path.GetExtension(filePath); fileFragment["Path"] = savePath; fileFragment["DataLength"] = 0; fileFragment["MsgID"] = -1; fileFragment["State"] = (byte)0; _isCancelUpload = false; _isWorking = true; int offset = 0; while (remaining >= 0 && _isWorking) { if (_isCancelUpload) { fileFragment["State"] = (byte)3; } switch ((byte)fileFragment["State"]) { case 0: //文件传送开始 //第一次发送文件,发送一些基本信息(如文件名等) fileFragment["DataLength"] = 0; fileFragment["Data"] = null; break; case 1: //文件传送中 fStream.Seek((int)fileFragment["MsgID"] * _bufferLength, SeekOrigin.Begin); fileFragment["DataLength"] = fStream.Read(buffer, offset, buffer.Length - offset); fileFragment["Data"] = buffer; //重置剩余数据长度 remaining = fileSize - ((int)fileFragment["MsgID"] * _bufferLength + (int)fileFragment["DataLength"]); if (remaining == 0) { _isWorking = false; remaining = -1; fileFragment["State"] = (byte)2; } break; case 3: //中断文件传送 fileFragment["DataLength"] = 0; fileFragment["Data"] = null; _isWorking = false; break; } //序列化 TSerializer serializer = new TBinarySerializer(); DynSerialize.WriteDynObject(serializer, fileFragment); byte[] data = serializer.ToBytes(); serializer.Flush(); DynObject repFragment = Transfer(_serverPort, data, 0); fileFragment["State"] = repFragment["State"]; fileFragment["MsgID"] = repFragment["MsgID"]; //向外界通知文件传送进度 if (ProgressEvent != null) { ProgressEvent(fileSize, fileSize - remaining); } } } }
/// <summary> /// 分发接收到的数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ReceiveReady(object sender, SocketEventArgs e) { ZmqSocket socket = e.Socket; ZmqMessage zmqMessage = socket.ReceiveMessage(); VirtuaIP destVIP = new VirtuaIP(zmqMessage[2].Buffer); //如果目标地址和本地路由一致转发到应用程序 ,如果不一致转发到Router if (destVIP.Router == _localVIP.Router && destVIP.Node == _localVIP.Node) { if (zmqMessage.FrameCount == 6) { /* * 把收到的本地数据转发到应用程序--共六帧数据 * 0、目的端口 * 1、空帧 * 2、源地址 * 3、目的端口 * 4、源端口 * 5、数据 * */ socket.SendMore(zmqMessage[3].Buffer); socket.SendMore(zmqMessage[1].Buffer); socket.SendMore(zmqMessage[2].Buffer); socket.SendMore(zmqMessage[3].Buffer); socket.SendMore(zmqMessage[4].Buffer); socket.Send(zmqMessage[5].Buffer); } else if (zmqMessage.FrameCount == 7) { /* * 把收到的远端数据转发到应用程序--共五帧数据 * 0、目的端口 * 1、空帧 * 2、源地址 * 3、目的端口 * 4、源端口 * 5、数据 * */ socket.SendMore(zmqMessage[4].Buffer); socket.SendMore(zmqMessage[1].Buffer); socket.SendMore(zmqMessage[3].Buffer); socket.SendMore(zmqMessage[4].Buffer); socket.SendMore(zmqMessage[5].Buffer); socket.Send(zmqMessage[6].Buffer); } //不符合要求的帧丢弃 } else if (zmqMessage.FrameCount == 6) { /* * 转发到Router--共七帧数据 * 0、下一跳地址 * 1、空帧 * 2、目的地址 * 3、源地址 * 4、目的端口 * 5、源端口 * 6、数据 * */ socket.SendMore(_nextVIP.ToBytes());//下一跳地址 socket.SendMore(zmqMessage[1].Buffer); socket.SendMore(zmqMessage[2].Buffer); socket.SendMore(_localVIP.ToBytes()); socket.SendMore(zmqMessage[3].Buffer); socket.SendMore(zmqMessage[4].Buffer); socket.Send(zmqMessage[5].Buffer); } //不符合要求的帧丢弃 }
/// <summary> /// 根据消息的目的地址,对消息进行转发 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ReceiveReady(object sender, SocketEventArgs e) { ZmqSocket socket = e.Socket; ZmqMessage zmqMessage = socket.ReceiveMessage(); //不符合要求的包直接丢掉 if (zmqMessage.FrameCount != 7) { return; } VirtuaIP destVIP = new VirtuaIP(zmqMessage[2].Buffer); #region 统计收到的数据包数量,转发速度p/s(每秒多少个包),并通知主线程更新界面 //byte[] data = zmqMessage[6].Buffer; //byte flage = data[0]; //switch (flage) //{ // case 0: count++; count = 1; break; // case 1: count++; break; // case 2: count++; ; break; //} //if (DataAnalysis != null) // DataAnalysis("in", count); #endregion #region 转发数据 if (destVIP.Router == _localVIP.Router) { if (destVIP.Node == _localVIP.Node) { //Router自己处理 Console.WriteLine("我的消息:{0}", Encoding.Unicode.GetString(zmqMessage[5].Buffer)); } else { /* * 接收数据--共六帧数据 * 0、目的地址 * 1、空帧 * 2、目的地址 * 3、源地址 * 4、目的端口 * 5、源端口 * 6、数据 * */ socket.SendMore(zmqMessage[2].Buffer); socket.SendMore(zmqMessage[1].Buffer); socket.SendMore(zmqMessage[2].Buffer); socket.SendMore(zmqMessage[3].Buffer); socket.SendMore(zmqMessage[4].Buffer); socket.SendMore(zmqMessage[5].Buffer); socket.Send(zmqMessage[6].Buffer); //如果推断不错的话,这里应该是发往本机的应用程序服务器端 } } else { /* * 转发到Router--共七帧数据 * 0、新的下一跳Router地址 * 1、空帧 * 2、目的地址 * 3、源地址 * 4、目的端口 * 5、源端口 * 6、数据 * */ //转发的下一个Router //得到下一跳地址 ushort nodeID = destVIP.Router; //TODO 此处可能得不到下一跳节点,因为目的节点不可到达,异常捕获比一般的判断速度慢10倍 ushort nextRouterID = _nextTripRouterDic[nodeID]; //得到连接到下一跳router的dealer RouterDealer dealer = _dealers[nextRouterID]; //dealer.Socket.SendMore(nextRouterVIP.ToBytes());//下一跳地址 dealer.Socket.SendMore(zmqMessage[1].Buffer); dealer.Socket.SendMore(zmqMessage[2].Buffer); dealer.Socket.SendMore(zmqMessage[3].Buffer); dealer.Socket.SendMore(zmqMessage[4].Buffer); dealer.Socket.SendMore(zmqMessage[5].Buffer); dealer.Socket.Send(zmqMessage[6].Buffer); //if (DataAnalysis != null) // DataAnalysis("out", count); } #endregion 转发数据 }
/// <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; } } } }
private void OnServer() { using (ZmqSocket serverSocket = _context.CreateSocket(SocketType.DEALER)) { serverSocket.Identity = BitConverter.GetBytes(_ftpServerPort); serverSocket.SendHighWatermark = 100000; bool isConnected = false; while (!isConnected) { try { serverSocket.Connect(_inprocHost); isConnected = true; } catch { Thread.Sleep(500); } } while (_isRunning) { string responseData = null; VirtuaIP originVIP = null; ushort originPort = 0; try { ZmqMessage zmqMessage = serverSocket.ReceiveMessage(TimeSpan.MaxValue); if (zmqMessage.FrameCount == 0) { throw new FtpException(); } originVIP = new VirtuaIP(zmqMessage[1].Buffer); originPort = (ushort)BitConverter.ToInt16(zmqMessage[3].Buffer, 0); byte[] requestMsg = zmqMessage[zmqMessage.FrameCount - 1].Buffer; //当有传送文件的请求时,创建一个Client和客户端通信,并把Client的端口返回给客户端--TODO ushort port = RockContext.GetAvailablePort(); string requestType = _encoding.GetString(requestMsg); Client client = new Client(port, _context, this, requestType); client.OnException = OnException; client.Start(); responseData = "Success:" + port; Thread.Sleep(2000); } catch (ThreadInterruptedException) { continue; } catch (FtpException) { continue; } catch (Exception e) { if (OnException != null) { OnException(e); } responseData = "Error:" + e.Message; } /* * 发送数据--共三帧 * 0、空帧 * 1、目的地址 * 2、目的端口 * 3、源端口 * 4、数据 * */ serverSocket.SendMore(_emptyFrame); serverSocket.SendMore(originVIP.ToBytes()); serverSocket.SendMore(BitConverter.GetBytes(originPort)); serverSocket.SendMore(BitConverter.GetBytes(_ftpServerPort)); serverSocket.Send(_encoding.GetBytes(responseData)); } } }
public void Send(string recvAddress, ushort destVPort, string data) { VirtuaIP receiverVIP = new VirtuaIP(recvAddress); Send(receiverVIP, destVPort, Encoding.UTF8.GetBytes(data)); }