using System; using System.Collections.Concurrent; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; namespace VideoReader { internal class InOutSocket { public int bitrateout = 0; public int bitratein = 0; private static byte[] keyByte = MD5("73!2#qweaSdzxc4r"); private static byte[] ivByte = MD5("0_=op[l:',./vf73"); private bool open; private ServerConfig config; private ConcurrentQueue outbuffer = new ConcurrentQueue(); private BinaryWriter bw; private ConcurrentQueue output = new ConcurrentQueue(); private bool noblock = true; // Новые поля для детального логгирования private TcpClient tcpClient; private NetworkStream networkStream; private Thread receiveThread; private Thread sendThread; private bool isRunning = false; private long packetCounter = 0; private DateTime connectionStartTime; public bool opened { get { return open; } set { open = value; } } public InOutSocket() { config = ServerConfig.LoadConfig(); DetailedLogger.LogConnection($"InOutSocket initialized with server: {config.ServerAddress}:{config.Port}"); DetailedLogger.LogDebug($"Encryption keys initialized - Key: {BitConverter.ToString(keyByte)}, IV: {BitConverter.ToString(ivByte)}"); } private static byte[] MD5(string input) { using (var md5 = System.Security.Cryptography.MD5.Create()) { return md5.ComputeHash(Encoding.UTF8.GetBytes(input)); } } public void Connect() { try { connectionStartTime = DateTime.Now; DetailedLogger.LogConnection($"Starting connection to {config.ServerAddress}:{config.Port}..."); // DNS Resolution DetailedLogger.LogDebug($"Resolving DNS for {config.ServerAddress}..."); var addresses = Dns.GetHostAddresses(config.ServerAddress); DetailedLogger.LogDebug($"DNS resolved to {addresses.Length} addresses: {string.Join(", ", addresses.Select(a => a.ToString()))}"); // TCP Connection tcpClient = new TcpClient(); tcpClient.ReceiveTimeout = 30000; // 30 seconds tcpClient.SendTimeout = 30000; var connectTask = tcpClient.ConnectAsync(config.ServerAddress, config.Port); var sw = Stopwatch.StartNew(); DetailedLogger.LogConnection($"Attempting TCP connection to {config.ServerAddress}:{config.Port}..."); connectTask.Wait(10000); // 10 second timeout if (!tcpClient.Connected) { throw new Exception($"Failed to connect within timeout"); } sw.Stop(); DetailedLogger.LogConnection($"TCP connection established in {sw.ElapsedMilliseconds}ms"); networkStream = tcpClient.GetStream(); DetailedLogger.LogDebug($"Network stream obtained, available: {networkStream.DataAvailable}"); // Start monitoring threads isRunning = true; receiveThread = new Thread(ReceiveLoop) { IsBackground = true, Name = "ReceiveThread" }; sendThread = new Thread(SendLoop) { IsBackground = true, Name = "SendThread" }; receiveThread.Start(); sendThread.Start(); DetailedLogger.LogConnection("Monitoring threads started"); // Send initial handshake SendInitialHandshake(); opened = true; DetailedLogger.LogConnection("Connection established successfully"); } catch (Exception ex) { DetailedLogger.LogError($"Connection failed: {ex.Message}", ex); opened = false; Cleanup(); throw; } } public void Disconnect() { DetailedLogger.LogConnection("Starting disconnect procedure..."); isRunning = false; opened = false; try { // Send disconnect packet if possible if (networkStream != null && tcpClient != null && tcpClient.Connected) { var disconnectPacket = Encoding.UTF8.GetBytes("DISCONNECT"); SendPacket(disconnectPacket, "Disconnect command"); } } catch (Exception ex) { DetailedLogger.LogError($"Error sending disconnect packet: {ex.Message}"); } Cleanup(); var totalTime = DateTime.Now - connectionStartTime; DetailedLogger.LogConnection($"Disconnected from server (session duration: {totalTime.TotalSeconds:F1}s, packets processed: {packetCounter})"); } private void Cleanup() { try { networkStream?.Close(); networkStream?.Dispose(); tcpClient?.Close(); tcpClient?.Dispose(); // Wait for threads to finish receiveThread?.Join(2000); sendThread?.Join(2000); DetailedLogger.LogDebug("Connection cleanup completed"); } catch (Exception ex) { DetailedLogger.LogError($"Error during cleanup: {ex.Message}"); } } } }