internal Status Send(Package package) { if (package == null) { s_log.ErrorFormat("Cannot send null package."); return Status.Failure; } if (m_socket == null || m_socket.Connected == false) { s_log.ErrorFormat("Socket not connected!"); return Status.Failure; } try { SendBytes(package.GetBytes()); } catch (Exception e) { s_log.ErrorFormat("Error sending Package({0}): {1}", package.GetSize(), e.Message); } return Status.NoResult; }
/// <summary> /// Synchronous method that waits for the specific handshake to arrive /// from the socket connection. /// </summary> /// <param name="serverHello">The received handshake.</param> /// <returns> /// Status.Failure if the handshake was not received within 30 seconds. /// </returns> internal Status ReceiveHandshake(out Package serverHello) { serverHello = null; TimeSpan timeout = new TimeSpan(0, 0, 30); // Loop indefinitely while waiting for the handshake response. // Note that the ResetEvent may wait up to 30 seconds each time a // signal is received from the socket's thread. while (true) { lock (m_receiveQueue) { // Break this loop only if we've received 8 or more bytes. if (m_receiveQueue.Count >= 8) break; } // Wait for "data received" notification from the socket. // If this returns false, the wait has timed out. if (m_receiveEvent.WaitOne(timeout) == false) { s_log.ErrorFormat("Timed out waiting for response."); return Status.Failure; } } serverHello = new Package(); List<byte> receivedBytes = new List<byte>(); lock (m_receiveQueue) { for (int i = 0; i < 8; i++) receivedBytes.Add(m_receiveQueue.Dequeue()); } serverHello.ReceivedBytes(receivedBytes); return Status.Success; }
public Status Connect() { OnProgressUpdated(new ProgressUpdatedEventArgs("Connect to Server", 0)); Disconnect(); // Only create a new Connection if we've never made one before. // Otherwise we re-use the same socket. OnProgressUpdated(new ProgressUpdatedEventArgs("Connect to Server", 10)); if (m_channel == null) m_channel = new Connection(); // Establish TCP connection. OnProgressUpdated(new ProgressUpdatedEventArgs("Connect to Server", 20)); if (m_channel.Connect(this) == Status.Failure) return Status.Failure; // Send Hotline handshake. OnProgressUpdated(new ProgressUpdatedEventArgs("Connect to Server", 30)); Package clientHello = new Package(new RawString("TRTPHOTL"), 0, 1, 0, 2); if (m_channel.Send(clientHello) == Status.Failure) return Status.Failure; // Start the socket data reader thread so incoming data will fill our byte queue. OnProgressUpdated(new ProgressUpdatedEventArgs("Connect to Server", 50)); m_channel.BeginSocketReceive(); // Read the handshake response from the server. OnProgressUpdated(new ProgressUpdatedEventArgs("Connect to Server", 60)); Package serverHello; if (m_channel.ReceiveHandshake(out serverHello) == Status.Failure) return Status.Failure; // Confirm the correct handshake response. OnProgressUpdated(new ProgressUpdatedEventArgs("Connect to Server", 70)); if (serverHello != new Package(new RawString("TRTP"), 0, 0, 0, 0)) { s_log.ErrorFormat("Incorrect handshake received."); return Status.Failure; } s_log.InfoFormat("Correct handshake received!"); // Specify the delegate to call when a transaction is received. OnProgressUpdated(new ProgressUpdatedEventArgs("Connect to Server", 80)); m_channel.TransactionReceived += ReceiveTransaction; m_channel.SocketException += HandleSocketException; // Start the socket listening for transactions. m_channel.ListenForTransactions(); // Start keep-alive timer. OnProgressUpdated(new ProgressUpdatedEventArgs("Connect to Server", 90)); StartKeepAlive(); return Status.Success; }