167 lines
6.1 KiB
C#
167 lines
6.1 KiB
C#
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<byte[]> outbuffer = new ConcurrentQueue<byte[]>();
|
|
private BinaryWriter bw;
|
|
private ConcurrentQueue<byte[]> output = new ConcurrentQueue<byte[]>();
|
|
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}");
|
|
}
|
|
}
|
|
}
|
|
} |