public static bool SendEx(IntPtr socket, Timeout timeout, string text) { var size = text.Length; if (!SendEx(socket, timeout, &size, sizeof(int))) return false; if (size == 0) return true; var buffer = new byte[size]; for (var index = 0; index < size; ++index) { buffer[index] = (byte)text[index]; } fixed (byte* ptr = &buffer[0]) { return SendEx(socket, timeout, ptr, size); } }
static bool ReceiveEx(IntPtr socket, Timeout timeout, void* data, int size) { var set = fd_set.Create(socket); var buffer = (byte*)data; for (; size > 0; ) { var t = timeout.ToTime(); var status = WinAPI.select(1, &set, null, null, &t); if (status != 1) return false; status = WinAPI.recv(socket, buffer, size, 0); if (status <= 0) return false; buffer += status; size -= status; } return true; }
public static bool ReceiveEx(IntPtr socket, Timeout timeout, MemoryBuffer data) { var set = fd_set.Create(socket); data.Reset(); var length = data.Capacity; var buffer = (byte*)data.Data; var total = 0; for (; total < 4; ) { var interval = timeout.ToTime(); var status = WinAPI.select(1, &set, null, null, &interval); if (status == 0) return false; status = WinAPI.recv(socket, buffer, length, 0); if (status <= 0) return false; buffer += status; total += status; length -= status; } data.Construct(total); var size = data.ReadInt32(); data.Construct(sizeof(int) + size); length = size - total + sizeof(int); // remaining data length if (length < 0) // we read more than expected return false; if (length == 0) // we read all data return true; buffer = (byte*)data.Data; buffer += total; for (; length > 0; ) { var interval = timeout.ToTime(); var status = WinAPI.select(1, &set, null, null, &interval); if (status == 0) return false; status = WinAPI.recv(socket, buffer, length, 0); if (status <= 0) return false; buffer += status; length -= status; } return true; }
public static bool ReceiveEx(IntPtr socket, Timeout timeout, out int value) { var temporary = 0; var result = ReceiveEx(socket, timeout, &temporary, sizeof(int)); value = temporary; return result; }
public static bool SendEx(IntPtr socket, Timeout timeout, int value) { return SendEx(socket, timeout, &value, sizeof(int)); }
public static bool ReceiveEx(IntPtr socket, Timeout timeout, out string text) { text = string.Empty; var size = 0; if (!ReceiveEx(socket, timeout, &size, sizeof(int))) return false; if (size < 0) return false; if (size == 0) return true; var buffer = new sbyte[size]; var result = false; fixed (sbyte* ptr = &buffer[0]) { result = ReceiveEx(socket, timeout, ptr, size); if (result) text = new string(ptr, 0, size); } return result; }
string ReciveText(ref Timeout timeout) { using (var buffer = MemoryBuffer.CreateLocal(4)) { this.Receive(buffer, ref timeout); return buffer.ReadAString(); } }
unsafe void Receive(MemoryBuffer data, ref Timeout timeout) { data.Reset(); var set = fd_set.Create(this.socket.Handle); var empty = fd_set.Null; // receiving package size and any additional data var length = data.Capacity; var buffer = (byte*)data.Data; var total = 0; for (; total < 4;) { var interval = timeout.ToTime(); var status = WinAPI.select(1, &set, null, null, &interval); if (status == 0) throw new TimeoutException("Timeout of receiving has been reached."); status = WinAPI.recv(this.socket.Handle, buffer, length, 0); if (status <= 0) throw new DisconnectedException(); buffer += status; total += status; length -= status; } data.Construct(total); var size = data.ReadInt32(); data.Construct(sizeof(int) + size); length = size - total + sizeof(int); // remaining data length if (length < 0) // we read more than expected throw new DisconnectedException(); if (length == 0) // we read all data return; buffer = (byte*)data.Data; buffer += total; for (; length > 0; ) { var interval = timeout.ToTime(); var status = WinAPI.select(1, &set, null, null, &interval); if (status == 0) throw new TimeoutException("Timeout of receiving has been reached."); status = WinAPI.recv(this.socket.Handle, buffer, length, 0); if (status <= 0) throw new DisconnectedException(); buffer += status; length -= status; } }
unsafe void Send(MemoryBuffer data, ref Timeout timeout) { var length = data.Size; var buffer = (Byte*)data.Data; var set = fd_set.Create(this.socket.Handle); for (; length > 0; ) { var interval = timeout.ToTime(); var status = WinAPI.select(1, null, &set, null, &interval); if (status == 0) throw new TimeoutException("Timeout of sending has been reached."); status = WinAPI.send(this.socket.Handle, buffer, length, 0); if (status <= 0) throw new DisconnectedException(); buffer += status; length -= status; } }
void SendText(string text, ref Timeout timeout) { using (var buffer = MemoryBuffer.CreateLocal()) { buffer.WriteAString(text); this.Send(buffer, ref timeout); } }
/// <summary> /// /// </summary> /// <param name="componentId"></param> /// <param name="methodId"></param> /// <param name="data"></param> /// <returns></returns> public override int Invoke(ushort componentId, ushort methodId, MemoryBuffer data) { if (this.socket == null) throw new DisconnectedException(); var size = data.Size; if (size < sizeof(Int32)) throw new ArgumentException("Memory buffer is too small", "data"); data.Position = 0; data.WriteInt32(size - 4); try { data.Position = 12; this.Translate(ref componentId, ref methodId); data.Position = 12; data.WriteUInt16(componentId); data.WriteUInt16(methodId); var timeout = new Timeout(this.Timeout); this.Send(data, ref timeout); this.Receive(data, ref timeout); data.Position = 12; int result = data.ReadInt32(); return result; } catch { this.Dispose(); throw; } }
/// <summary> /// The methods tries to send an empty request and receive answer. /// The method closes the connection, if ping operation is failed; in this case you should connect the client again. /// </summary> /// <param name="timeoutInMilliseconds">Timeout in milliseconds for sending request and receiving response</param> /// <returns> /// true, if request has been sent and response has been received. /// false, if request has not been send or response has not been received or the client is disconnected. /// </returns> public bool Ping(int timeoutInMilliseconds) { if (this.socket == null) return false; using (var buffer = MemoryBuffer.CreateRemote(ushort.MaxValue, ushort.MaxValue)) { try { buffer.Position = 0; buffer.WriteInt32(buffer.Size - sizeof(int)); var timeout = new Timeout(timeoutInMilliseconds); this.Send(buffer, ref timeout); this.Receive(buffer, ref timeout); return true; } catch (TimeoutException) { this.Dispose(); return false; } catch (DisconnectedException) { this.Dispose(); return false; } } }
/// <summary> /// Connecting the single-threaded client to a remote server. /// </summary> /// <param name="timeoutInMilliseconds">Timeout of logical connection.</param> /// <returns>true, if connection has been established, otherwise false</returns> public bool Connect(int timeoutInMilliseconds) { if (this.socket != null) { this.logger.Output("Closing socket"); this.socket.Close(); this.socket = null; this.logger.Output("Socket has been closed"); } this.logger.Output("Creating a new socket"); var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { this.logger.Output("New socket has been created"); this.logger.Output("Connectiong to {0}:{1}", this.address, this.port); socket.Connect(this.address, this.port); this.logger.Output("New connection has been established"); this.logger.Output("Enabling keep alive"); var keepalive = new TcpKeepalive(true, 10000, 3000); keepalive.Apply(socket); var timeout = new Timeout(timeoutInMilliseconds); this.logger.Output("Sending protocol version = {0}", ProtocolVersion.Initial); // send protocol version if (!Network.SendEx(socket.Handle, timeout, ProtocolVersion.Initial)) { this.logger.Output("Could not send protocol version"); return false; } this.logger.Output("Protocol version has been sent"); int answer = HResult.S_OK; this.logger.Output("Receiving server protocol answer"); if (!Network.ReceiveEx(socket.Handle, timeout, out answer)) { this.logger.Output("Could not receive server protocol answer"); return false; } this.logger.Output("Server protocol answer: code = {0}; status = {1}", answer, HResult.Succeeded(answer)); if (HResult.Failed(answer)) { return false; } this.logger.Output("Sending username = {0}", this.username); if (!Network.SendEx(socket.Handle, timeout, this.username)) { this.logger.Output("Could not send username"); return false; } this.logger.Output("Username has been sent"); this.logger.Output("Sending password = {0}", this.password); if (!Network.SendEx(socket.Handle, timeout, this.password)) { this.logger.Output("Could not send password"); return false; } this.logger.Output("Password has been sent"); answer = HResult.S_OK; this.logger.Output("Receiving server authorization answer"); if (!Network.ReceiveEx(socket.Handle, timeout, out answer)) { this.logger.Output("Could not receive server authorization answer"); return false; } this.logger.Output("Server authorization answer: code = {0}; status = {1}", answer, HResult.Succeeded(answer)); if (HResult.Failed(answer)) { return false; } this.logger.Output("Receiving remote signature"); string remoteSignature; if (!Network.ReceiveEx(socket.Handle, timeout, out remoteSignature)) { this.logger.Output("Could not receive remote signature"); return false; } this.logger.Output("Remote signature has been received = {0}", remoteSignature); this.logger.Output("Initializing translators"); this.Initialize(remoteSignature); this.logger.Output("Translators have been initialized"); this.socket = socket; } finally { if (this.socket != socket) { socket.Close(); } } this.FlushTranlators(this.logger); return true; }