예제 #1
0
파일: Network.cs 프로젝트: ifzz/FDK
        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);
            }
        }
예제 #2
0
파일: Network.cs 프로젝트: ifzz/FDK
        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;
        }
예제 #3
0
파일: Network.cs 프로젝트: ifzz/FDK
        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;
        }
예제 #4
0
파일: Network.cs 프로젝트: ifzz/FDK
 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;
 }
예제 #5
0
파일: Network.cs 프로젝트: ifzz/FDK
 public static bool SendEx(IntPtr socket, Timeout timeout, int value)
 {
     return SendEx(socket, timeout, &value, sizeof(int));
 }
예제 #6
0
파일: Network.cs 프로젝트: ifzz/FDK
        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;
        }
예제 #7
0
파일: StClient.cs 프로젝트: ifzz/FDK
 string ReciveText(ref Timeout timeout)
 {
     using (var buffer = MemoryBuffer.CreateLocal(4))
     {
         this.Receive(buffer, ref timeout);
         return buffer.ReadAString();
     }
 }
예제 #8
0
파일: StClient.cs 프로젝트: ifzz/FDK
        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;
            }
        }
예제 #9
0
파일: StClient.cs 프로젝트: ifzz/FDK
        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;
            }
        }
예제 #10
0
파일: StClient.cs 프로젝트: ifzz/FDK
 void SendText(string text, ref Timeout timeout)
 {
     using (var buffer = MemoryBuffer.CreateLocal())
     {
         buffer.WriteAString(text);
         this.Send(buffer, ref timeout);
     }
 }
예제 #11
0
파일: StClient.cs 프로젝트: ifzz/FDK
        /// <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;
            }
        }
예제 #12
0
파일: StClient.cs 프로젝트: ifzz/FDK
        /// <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;
                }
            }
        }
예제 #13
0
파일: StClient.cs 프로젝트: ifzz/FDK
        /// <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;
        }