示例#1
0
文件: Node.cs 项目: lulzzz/kino
 private int CalculateHashCode()
 {
     unchecked
     {
         return((Uri.GetHashCode() * 397) ^ SocketIdentity.ComputeHash());
     }
 }
示例#2
0
 public UNetClient(IPacketProcessor packetProcessor)
 {
     _channelManager = new ChannelManager();
     PacketProcessor = packetProcessor;
     ActiveChannels  = new List <IClientChannel> {
         CreateMainChannel()
     };
     Identity        = new SocketIdentity(0);
     _operationTable = new Dictionary <int, ISocketOperation>();
 }
示例#3
0
 public Peer(int id, Socket sock, uint bufferSize, Guid guid, IServerChannel hostChannel)
 {
     Identity = new SocketIdentity(id, guid);
     _sock    = sock;
     _sock.ReceiveBufferSize = _bufferSize = (int)bufferSize;
     _buffObj = new BufferObject((int)bufferSize);
     _activeSequenceSessions = new Dictionary <Guid, SequenceSession>();
     _netWriter  = new NetworkWriter();
     _lockObj    = new object();
     HostChannel = hostChannel;
     _netReader  = new NetworkReader();
     Endpoint    = (IPEndPoint)_sock.RemoteEndPoint;
 }
示例#4
0
        /// <summary>
        /// 应在 ReceiveData() 最开始调用
        /// 接收 KeyBytes, 调用 CheckIdentity();
        /// 向 Dictionary 添加 SocketResponder 权限;
        /// 并向 Client 端返回 SocketIdentity
        /// </summary>
        /// <param name="responder"></param>
        private void ResponseIdentity(SocketResponder responder)
        {
            responder.ReceiveBytes(out HB32Header header, out byte[] bytes);
            SocketIdentityCheckEventArgs e = new SocketIdentityCheckEventArgs(header, bytes);

            CheckIdentity(this, e);
            SocketIdentity identity = e.CheckedIndentity;

            lock (ClientIdentitiesLock)
            {
                ClientIdentities.Add(responder, identity);
            }
            responder.SendHeader(SocketPacketFlag.AuthenticationResponse, i1: (int)identity);
        }
        /// <summary>
        /// 相应 client 端的 fsid 请求
        /// 文件占用 (文件活跃时间超时被自动清除) 时返回对应 fsid , 否则生成新fsid并返回
        /// 记录在 ServerFileSet 中
        /// </summary>
        /// <param name="client"></param>
        /// <param name="header">依据header判断上传/下载</param>
        /// <param name="bytes"></param>
        private void ResponseFileStreamId(Socket client, HB32Header header, byte[] bytes)
        {
            string           err_msg = "";
            SocketPacketFlag mask    = header.Flag & (SocketPacketFlag)(1 << 8);
            int fsid = -1;

            try
            {
                SocketIdentity required_identity = (mask > 0) ? SocketIdentity.WriteFile : SocketIdentity.ReadFile;
                if ((GetIdentity(client) & required_identity) == 0)
                {
                    throw new Exception("Socket not authenticated.");
                }

                string path = Encoding.UTF8.GetString(bytes);
                if (IsFileOccupying(path, out fsid))
                {
                    ;
                }
                else
                {
                    FileInfo   fif = new FileInfo(path);
                    FileStream fs  = new FileStream(path, FileMode.OpenOrCreate, (mask > 0) ? FileAccess.Write : FileAccess.Read);
                    SocketServerFileStreamInfo record = new SocketServerFileStreamInfo
                    {
                        FStream    = fs,
                        ServerPath = path,
                        Length     = fif.Length,
                    };
                    fsid = GenerateRandomFileStreamId(1 << 16);
                    ServerFileSet.Add(fsid, record);
                }
            }
            catch (Exception ex)
            {
                err_msg = ex.Message;
            }
            if (string.IsNullOrEmpty(err_msg))
            {
                SendBytes(client, new HB32Header {
                    Flag = SocketPacketFlag.DownloadAllowed | mask
                }, fsid.ToString());
            }
            else
            {
                SendBytes(client, new HB32Header {
                    Flag = SocketPacketFlag.DownloadDenied | mask
                }, err_msg);
            }
        }
示例#6
0
        private void AcceptCallback(IAsyncResult res)
        {
            if (!IsActive)
            {
                return;
            }
            var newSock = ChannelSocket.EndAccept(res);

            Peer.Peer newPeer;
            if (IsMainChannel)
            {
                newPeer = new Peer.Peer(new SocketIdentity(Manager.GeneratePeerId(), SocketIdentity.GenerateGuid()), newSock, BufferSize, this);
                newPeer.OnPeerDisconnected += (o, e2) =>
                {
                    OnPeerDisconnected.Raise(o, new ChannelEventArgs(this, newPeer));
                };
                newPeer.Receive();
                AcceptPeer(newPeer);
            }
            else
            {
                newPeer = new Peer.Peer(new SocketIdentity(Manager.GeneratePeerId()), newSock, BufferSize, this);
                PendingConnections.Add(new PendingPeerConnection(newPeer.Identity.Guid, newPeer));
                newPeer.OnPeerDisconnected += (o, e2) =>
                {
                    OnPeerDisconnected.Raise(o, new ChannelEventArgs(this, newPeer));
                };
                newPeer.Receive();
                newPeer.OnPeerRelocationRequest += (sender, e) =>
                {
                    if (PendingConnections.FirstOrDefault(pc => pc.Guid == e.PeerGuid && !pc.IsCancelled) != null)
                    {
                        AcceptPeer(newPeer);
                        OnPeerConnected.Raise(this, new ChannelEventArgs(this, e.Peer));

                        lock (_lockObj)
                            PendingConnections.Remove(PendingConnections.First(pc => pc.Guid == e.PeerGuid));
                    }
                };
            }
            ChannelSocket.BeginAccept(AcceptCallback, null);
        }
示例#7
0
        public void AddPeerToChannel(IServerChannel channel, SocketIdentity identity)
        {
            var peer = ((IServerChannel)GetMainChannel()).ConnectedPeers.FirstOrDefault(p => p.Identity.Equals(identity));

            if (peer == null)
            {
                throw new ChannelOperationException("Could not locate peer");
            }

            var relocationPacket = new PeerRelocationRequestPacket
            {
                ChannelId = channel.Id,
                PeerGuid  = peer.Identity.Guid,
                Operation = PeerRelocationRequestPacket.RelocateOperation.Join,
                Port      = (int)channel.Port
            };

            lock (_channelLockObj)
                channel.PendingConnections.Add(new PendingPeerConnection(peer.Identity.Guid, peer));
            peer.SendData(relocationPacket, channel, null);
        }
示例#8
0
        //TODO: optimize this
        public ISequencePacket[] CreateSequence(IDataPacket packet, byte[] completeBuff, int buffSize,
                                                out SequenceInitPacket initPacket, out Guid seqGuid)
        {
            //  if (!IsSequenceRequired(buffSize, completeBuff.Length))
            //TODO: do proper shit..
            // throw new Exception();

            var modRest    = completeBuff.Length % (buffSize - 33);
            var outList    = CreateSequence(completeBuff, buffSize - 33, modRest, completeBuff.Length).ToArray();
            var curSeqGuid = seqGuid = SocketIdentity.GenerateGuid();

            initPacket = new SequenceInitPacket
            {
                PartsCount       = outList.Length,
                SequenceGuid     = seqGuid,
                FullSequenceSize = completeBuff.Length
            };
            for (var i = 0; i < outList.Length; i++)
            {
                outList[i].SeqGuid = curSeqGuid;
            }
            return(outList.ToArray());
        }
示例#9
0
文件: Node.cs 项目: lulzzz/kino
 public override string ToString()
 => $"{SocketIdentity.GetAnyString()}@{Uri.ToSocketAddress()}";
示例#10
0
 protected SocketOperationBase()
 {
     OperationGuid = SocketIdentity.GenerateGuid();
 }
示例#11
0
        public static void AsyncConnectForIdentity(ConnectionRoute route, SocketAsyncCallbackEventHandler asyncCallback, SocketAsyncExceptionEventHandler exceptionCallback)
        {
            Task.Run(() =>
            {
                try
                {
                    SocketIdentity identity = SocketIdentity.None;
                    SocketClient client     = new SocketClient(route.NextNode, route.IsNextNodeProxy);
                    //client.Connect(Config.SocketSendTimeout, Config.SocketReceiveTimeout);
                    client.ConnectWithTimeout(Config.BuildConnectionTimeout);
                    client.SetTimeout(Config.SocketSendTimeout, Config.SocketReceiveTimeout);
                    if (route.IsNextNodeProxy)
                    {
                        /// 向代理服务器申请建立与服务端通信隧道, 并等待隧道建立完成
                        client.SendBytes(SocketPacketFlag.ProxyRouteRequest, route.GetBytes(node_start_index: 1), i1: 0);
                        client.ReceiveBytes(out HB32Header header, out byte[] bytes);
                        if (header.Flag != SocketPacketFlag.ProxyResponse)
                        {
                            throw new Exception(string.Format("Proxy exception at depth {0} : {1}. {2}",
                                                              header.I1, route.ProxyRoute[header.I1], Encoding.UTF8.GetString(bytes)));
                        }
                    }
                    /// 获取 socket 权限
                    client.SendBytes(SocketPacketFlag.AuthenticationRequest, Config.KeyBytes);
                    client.ReceiveBytesWithHeaderFlag(SocketPacketFlag.AuthenticationResponse, out HB32Header auth_header);
                    identity = (SocketIdentity)auth_header.I1;
                    client.Close();
                    asyncCallback.Invoke(null, EventArgs.Empty);
                }
                catch (Exception ex)
                {
                    exceptionCallback.Invoke(null, new SocketAsyncExceptionEventArgs(ex));
                }
            });



            /*
             *
             * 原来这种方案同样是异步执行, 总会提前返回 SocketIdentity.None
             * SocketIdentity identity = SocketIdentity.None;
             * SocketClient client = new SocketClient(route.NextNode, route.IsNextNodeProxy);
             * client.SocketAsyncCallback += (object sender, EventArgs e) =>
             * {
             *  if (route.IsNextNodeProxy)
             *  {
             *      /// 向代理服务器申请建立与服务端通信隧道, 并等待隧道建立完成
             *      client.SendBytes(SocketPacketFlag.ProxyRouteRequest, route.GetBytes(node_start_index: 1));
             *      client.ReceiveBytesWithHeaderFlag(SocketPacketFlag.ProxyResponse);
             *  }
             *  /// 获取 socket 权限
             *  client.SendBytes(SocketPacketFlag.AuthenticationRequest, Config.KeyBytes);
             *  client.ReceiveBytesWithHeaderFlag(SocketPacketFlag.AuthenticationResponse, out HB32Header header);
             *  identity = (SocketIdentity)header.I1;
             *  client.Close();
             * };
             * client.SocketAsyncCallback += asyncCallback;
             * client.SocketAsyncException += exceptionCallback;
             * client.AsyncConnect(Config.SocketSendTimeout, Config.SocketReceiveTimeout);
             */
        }
示例#12
0
        /// <summary>
        /// 在 Socket.accept() 获取到的 client 在这里处理
        /// 这个函数为 client 的整个生存周期
        /// </summary>
        /// <param name="acceptSocketObject">client socket</param>
        public override void ReceiveData(object acceptSocketObject)
        {
            Socket client = (Socket)acceptSocketObject;

            try
            {
                client.SendTimeout    = Config.SocketSendTimeOut;
                client.ReceiveTimeout = Config.SocketReceiveTimeOut;
                this.ReceiveBytes(client, out HB32Header ac_header, out byte[] ac_bytes);
                SocketIdentity identity = CheckIdentity(ac_header, ac_bytes);
                ClientIdentities.Add(client, identity);
                this.SendHeader(client, SocketPacketFlag.AuthenticationResponse, (int)identity);
                int error_count = 0;
                while (flag_receive & error_count < 5)
                {
                    try
                    {
                        ReceiveBytes(client, out HB32Header header, out byte[] bytes);
                        switch (header.Flag)
                        {
                        case SocketPacketFlag.DirectoryRequest:
                            ResponseDirectory(client, bytes);
                            break;

                        case SocketPacketFlag.DirectorySizeRequest:
                            ResponseDirectorySize(client, bytes);
                            break;

                        case SocketPacketFlag.CreateDirectoryRequest:
                            ResponseCreateDirectory(client, bytes);
                            break;

                            #region download
                        case SocketPacketFlag.DownloadRequest:
                            ResponseDownloadSmallFile(client, bytes);
                            break;

                        case SocketPacketFlag.DownloadFileStreamIdRequest:
                            ResponseFileStreamId(client, header, bytes);
                            break;

                        case SocketPacketFlag.DownloadPacketRequest:
                            ResponseTransferPacket(client, header, bytes);
                            break;
                            #endregion

                            #region upload
                        case SocketPacketFlag.UploadRequest:
                            ResponseUploadSmallFile(client, bytes);
                            break;

                        case SocketPacketFlag.UploadFileStreamIdRequest:
                            ResponseFileStreamId(client, header, bytes);
                            break;

                        case SocketPacketFlag.UploadPacketRequest:
                            ResponseTransferPacket(client, header, bytes);
                            break;
                            #endregion

                        case SocketPacketFlag.StatusReport:
                            RecordStatusReport(client, bytes);
                            break;


                        case SocketPacketFlag.DisconnectRequest:
                            DisposeClient(client);
                            return;

                        default:
                            throw new Exception("Invalid socket header in receiving: " + header.Flag.ToString());
                        }
                        error_count = 0;
                    }
                    catch (SocketException ex)
                    {
                        error_count++;
                        switch (ex.ErrorCode)
                        {
                        // 远程 client 主机关闭连接
                        case 10054:
                            DisposeClient(client);
                            Log("Connection closed (client closed). " + ex.Message, LogLevel.Info);
                            return;

                        // Socket 超时
                        case 10060:
                            Thread.Sleep(200);
                            Log("Socket timeout. " + ex.Message, LogLevel.Trace);
                            continue;

                        default:
                            Log("Server receive data :" + ex.Message, LogLevel.Warn);
                            continue;
                        }
                    }
                    catch (Exception ex)
                    {
                        error_count++;
                        if (ex.Message.Contains("Buffer receive error: cannot receive package"))
                        {
                            DisposeClient(client);
                            Log(ex.Message, LogLevel.Trace);
                            return;
                        }
                        if (ex.Message.Contains("Invalid socket header"))
                        {
                            DisposeClient(client);
                            Log("Connection closed : " + ex.Message, LogLevel.Warn);
                            return;
                        }
                        Log("Server exception :" + ex.Message, LogLevel.Warn);
                        Thread.Sleep(200);
                        continue;
                    }
                }
                Log("Connection closed.", LogLevel.Warn);
            }
            catch (Exception ex)
            {
                Log("WTF ReceiveData exception :" + ex.Message, LogLevel.Error);
                ClientIdentities.Remove(client);
            }
        }
示例#13
0
 public void AddPeerToChannel(IServerChannel channel, SocketIdentity identity)
 {
     _channelMgr.AddPeerToChannel(channel, identity);
 }