private int CalculateHashCode() { unchecked { return((Uri.GetHashCode() * 397) ^ SocketIdentity.ComputeHash()); } }
public UNetClient(IPacketProcessor packetProcessor) { _channelManager = new ChannelManager(); PacketProcessor = packetProcessor; ActiveChannels = new List <IClientChannel> { CreateMainChannel() }; Identity = new SocketIdentity(0); _operationTable = new Dictionary <int, ISocketOperation>(); }
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; }
/// <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); } }
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); }
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); }
//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()); }
public override string ToString() => $"{SocketIdentity.GetAnyString()}@{Uri.ToSocketAddress()}";
protected SocketOperationBase() { OperationGuid = SocketIdentity.GenerateGuid(); }
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); */ }
/// <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); } }
public void AddPeerToChannel(IServerChannel channel, SocketIdentity identity) { _channelMgr.AddPeerToChannel(channel, identity); }