private void CloseClientSocket(SocketAsyncEventArgs e) { lock (closeLocker) { if (readEventArgs == null || Socket == null || !Connected || (Socket != null && !Socket.Connected)) { return; } AsyncUserToken token = e.UserToken as AsyncUserToken; if (token != null) { try { bool conn = Connected; Interlocked.CompareExchange(ref connected, Convert.ToInt32(false), Convert.ToInt32(true)); token.Socket.Shutdown(SocketShutdown.Both); if (ClientDisconnected != null && conn) { ClientDisconnected(this, new ClientDisconnectedEventArgs(this)); } if (InternalClientDisconnected != null && conn) { InternalClientDisconnected(this, new ClientDisconnectedEventArgs(this)); } } catch (Exception) { } finally { if (token.Socket != null) { token.Socket.Close(); } } } } }
public async Task StartReceive() { connected = Convert.ToInt32(true); AsyncUserToken token = (AsyncUserToken)readEventArgs.UserToken; Socket = token.Socket; Socket.NoDelay = true; RemoteEndPoint = (IPEndPoint)Socket.RemoteEndPoint; if (Direction == Direction.Client) { var afterPacket = Observable.FromEventPattern <PacketEventArgs>(p => AfterPacketReceived += p, p => AfterPacketReceived -= p); var heartbeatPacket = (from p in afterPacket where p.EventArgs.Packet.PacketId == (int)KnownPacket.Heartbeat select p).Timeout(TimeSpan.FromMinutes(1)); heartbeatChecker = heartbeatPacket.Subscribe(e => { }, e => { if (Server != null && Server.Player != null) { SharpStarLogger.DefaultLogger.Warn("Did not receive a heartbeat packet in a certain amount of time from player {0}. Kicking client!", Server.Player.Name); } else { SharpStarLogger.DefaultLogger.Warn("Did not receive a heartbeat packet in a certain amount of time. Kicking client!"); } ForceDisconnect(); if (OtherClient != null) { OtherClient.ForceDisconnect(); } }, () => { }); } bool willRaiseEvent = token.Socket.ReceiveAsync(readEventArgs); if (!willRaiseEvent) { await ProcessReceive(readEventArgs); } }
public void Connect(IPEndPoint ipe) { var connectArgs = new SocketAsyncEventArgs(); var token = new AsyncUserToken(); token.Socket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp); connectArgs.RemoteEndPoint = ipe; connectArgs.UserToken = token; connectArgs.Completed += connectArgs_Completed; token.Socket.ConnectAsync(connectArgs); SocketError errorCode = connectArgs.SocketError; if (errorCode != SocketError.Success) { new SocketException((int)errorCode).LogError(); } }
public async Task FlushPackets() { while (PacketQueue.Count > 0) { try { IPacket next; if (!PacketQueue.TryDequeue(out next)) { continue; } if (!next.IsReceive) { foreach (var handler in Server.PacketHandlers) { if (next.PacketId == handler.PacketId) { await handler.Handle(next, OtherClient); } } } if (next.Ignore) { continue; } var stream = new StarboundStream(); next.Write(stream); byte[] buffer = stream.ToArray(); bool compressed = stream.Length >= 512; if (compressed) { buffer = ZlibStream.CompressBuffer(buffer); } stream.Dispose(); int length = compressed ? -buffer.Length : buffer.Length; var finalStream = new StarboundStream(); finalStream.WriteUInt8(next.PacketId); finalStream.WriteSignedVLQ(length); finalStream.Write(buffer, 0, buffer.Length); byte[] toSend = finalStream.ToArray(); finalStream.Dispose(); if (Socket == null) { return; } var token = new AsyncUserToken(); token.Socket = Socket; SocketAsyncEventArgs writeArgs = new SocketAsyncEventArgs(); writeArgs.RemoteEndPoint = Socket.RemoteEndPoint; writeArgs.UserToken = token; writeArgs.SetBuffer(toSend, 0, toSend.Length); writeArgs.Completed += IO_Completed; Socket.SendAsync(writeArgs); } catch { CloseClientSocket(readEventArgs); } } }
private async Task ProcessReceive(SocketAsyncEventArgs e) { AsyncUserToken token = (AsyncUserToken)e.UserToken; if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { PacketReader.NetworkBuffer = new ArraySegment <byte>(e.Buffer, e.Offset, e.BytesTransferred); var packets = PacketReader.UpdateBuffer(true); foreach (IPacket packet in packets) { try { if (Server == null) { break; } EventHandler <PacketEventArgs> packetArgs = PacketReceived; if (packetArgs != null) { packetArgs(this, new PacketEventArgs(this, packet)); } var handlers = Server.PacketHandlers; foreach (IPacketHandler handler in handlers) { if (packet.PacketId == handler.PacketId) { await handler.Handle(packet, this); } } await SharpStarMain.Instance.PluginManager.CallEvent(packet, OtherClient); if (!packet.Ignore && OtherClient != null) { await OtherClient.SendPacket(packet); } foreach (IPacketHandler handler in handlers) { if (packet.PacketId == handler.PacketId) { await handler.HandleAfter(packet, this); } } EventHandler <PacketEventArgs> afterPacketArgs = AfterPacketReceived; if (afterPacketArgs != null) { afterPacketArgs(this, new PacketEventArgs(this, packet)); } await SharpStarMain.Instance.PluginManager.CallEvent(packet, OtherClient, true); } catch (Exception ex) { ex.LogError(); } } try { bool willRaiseEvent = token.Socket.ReceiveAsync(e); if (!willRaiseEvent) { await ProcessReceive(e); } } catch { } } else { CloseClientSocket(e); } }