示例#1
0
        /// <summary>
        /// This is generic function which will send UDP command to specific IP, port and return the
        /// reply if required
        /// </summary>
        /// <param name="socket">Socket - must be initialized</param>
        /// <param name="bytes2Send">Bytes to send to the given socket</param>
        /// <param name="replyRequired">Is reply required?</param>
        /// <returns>Reply packet</returns>
        public async Task <ReplyPacket> SendUdpAsync(UdpClient socket, byte[] bytes2Send, bool replyRequired = true)
        {
            ReplyPacket replyPacket = new ReplyPacket();

            if (socket is null)
            {
                replyPacket.Error = "Socket is null";
                return(replyPacket);
            }

            if (bytes2Send is null)
            {
                replyPacket.Error = "Bytes to send is null";
                return(replyPacket);
            }

            try
            {
                int bytesSent = await socket.SendAsync(bytes2Send, bytes2Send.Length).ConfigureAwait(false);

                replyPacket.IsSent = true;
                if (replyRequired)
                {
                    Task <UdpReceiveResult> taskRecievePacket = socket.ReceiveAsync();
                    taskRecievePacket.Wait(socket.Client.ReceiveTimeout);
                    if (taskRecievePacket.IsCompleted)
                    {
                        replyPacket.SetReply(taskRecievePacket.Result.Buffer);
                        replyPacket.IsSentAndReplyReceived = true;
                    }
                }
            }
            catch (Exception ex)
            {
                replyPacket.Error = ex.Message;
            }
            return(replyPacket);
        }
示例#2
0
        /// <summary>
        /// It will connect on the server with given IP and Port then listens on it. Use it in the thread/task
        /// </summary>
        /// <param name="ip">Server IP</param>
        /// <param name="port">Server Port</param>
        /// <param name="endBytesIdentifier">
        /// This identifies the end packet once receive these bytes it will push the packet. If null
        /// then it pushes as it receives
        /// </param>
        /// <param name="connectionTimeoutMs"></param>
        /// <param name="receiveTimeOut"></param>
        /// <param name="transmissionTimeout"></param>
        /// <returns>Connection Status</returns>
        public bool Connect(string ip, int port, byte[] endBytesIdentifier = null, int connectionTimeoutMs = 2000, int receiveTimeOut = 1000, int transmissionTimeout = 1000)
        {
            if (endBytesIdentifier != null)
            {
                endBytesIdentifier = endBytesIdentifier.Reverse().ToArray();
            }
            if (IsConnected)
            {
                return(IsConnected);
            }
            clientTcp = new TcpClient()
            {
                ReceiveTimeout = receiveTimeOut, SendTimeout = transmissionTimeout
            };

            try
            {
                IAsyncResult result  = clientTcp.BeginConnect(ip, port, null, null);
                bool         success = result.AsyncWaitHandle.WaitOne(connectionTimeoutMs, true);
                IsConnected = clientTcp.Connected;
                if (!IsConnected)
                {
                    return(IsConnected);
                }
                Port = port;
                Ip   = ip;
            }
            catch (Exception ex)
            {
                ExceptionHandler?.Invoke(this, ex);
                return(IsConnected);
            }

            try
            {
                stream = clientTcp.GetStream();
                ReplyPacket replyPacket = new ReplyPacket()
                {
                    IsSentAndReplyReceived = true, IPSender = ip
                };
                IsConnected = true;

                List <byte> completePacket = new List <byte>();
                Task.Run(async() =>
                {
                    while (clientTcp.Connected)
                    {
                        if (!IsConnected)
                        {
                            break;
                        }

                        if (!stream.DataAvailable)
                        {
                            await Task.Delay(1).ConfigureAwait(false);
                        }
                        else
                        {
                            try
                            {
                                byte[] packet = new byte[clientTcp.Available];
                                await stream.ReadAsync(packet, 0, packet.Length).ConfigureAwait(false);
                                completePacket.AddRange(packet);
                                int lenth = completePacket.Count;
                                if (endBytesIdentifier != null)
                                {
                                    //this will flush any data that was there before connecting to the software
                                    //if (lenth > 5000) { completePacket.Clear(); continue; }
                                    if (completePacket.Count > endBytesIdentifier.Length)
                                    {
                                        bool isPacketEndIdentified = false;
                                        for (int i = 0; i < endBytesIdentifier.Length; i++)
                                        {
                                            if (completePacket[lenth - (i + 1)] == endBytesIdentifier[i])
                                            {
                                                isPacketEndIdentified = true;
                                            }
                                            else
                                            {
                                                isPacketEndIdentified = false;
                                                break;
                                            }
                                        }
                                        if (isPacketEndIdentified)
                                        {
                                            replyPacket.SetReply(completePacket);
                                            DataReady?.Invoke(this, replyPacket);
                                            completePacket.Clear();
                                        }
                                    }
                                }
                                else
                                {
                                    replyPacket.SetReply(completePacket);
                                    DataReady?.Invoke(this, replyPacket);
                                    completePacket.Clear();
                                }
                            }
                            catch (Exception ex)
                            {
                                ExceptionHandler?.Invoke(this, ex);
                            }
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                ExceptionHandler?.Invoke(this, ex);
            }

            return(IsConnected);
        }
示例#3
0
        /// <summary>
        /// Returns the current status of listener
        /// </summary>
        /// <returns></returns>
        public bool StartListener()
        {
            if (IsListening)
            {
                return(IsListening);
            }
            IPAddress serverIP = IPAddress.Parse(Services.CommonUtility.GetIPAddress());

            listener = new TcpListener(serverIP, Port);

            try
            {
                listener.Start();
                IsListening = true;
            }
            catch (Exception ex)
            {
                IsListening = false;
                ExceptionHandler?.Invoke(null, ex);
                return(IsListening);
            }

            Task.Run(async() =>
            {
                while (IsListening)
                {
                    try
                    {
                        ReplyPacket replyPacket = new ReplyPacket()
                        {
                            IsSentAndReplyReceived = true
                        };
                        TcpClient clientTCP    = await listener.AcceptTcpClientAsync().ConfigureAwait(false);
                        replyPacket.PortSender = ((IPEndPoint)clientTCP.Client.RemoteEndPoint).Port;
                        replyPacket.IPSender   = ((IPEndPoint)clientTCP.Client.RemoteEndPoint).Address.ToString();
                        if (ReceiveFromThisIPAddressList.Count > 0)
                        {
                            bool isProcessingRequired = false;
                            foreach (var ipAcceptable in ReceiveFromThisIPAddressList)
                            {
                                if (ipAcceptable == replyPacket.IPSender)
                                {
                                    isProcessingRequired = true;
                                    break;
                                }
                            }
                            if (!isProcessingRequired)
                            {
                                continue;
                            }
                        }

                        int length;
                        NetworkStream stream     = clientTCP.GetStream();
                        List <byte> singlePacket = new List <byte>();
                        var byteArray            = new byte[1024];
                        while ((length = stream.Read(byteArray, 0, byteArray.Length)) != 0)
                        {
                            var copy = new byte[length];
                            Array.Copy(byteArray, 0, copy, 0, length);
                            singlePacket.AddRange(copy);
                        }
                        replyPacket.SetReply(singlePacket);
                        DataEvent?.Invoke(this, replyPacket);
                        if (IsAutoReplying)
                        {
                            await stream.WriteAsync(AutoReply?.ToArray(), 0, AutoReply.Count).ConfigureAwait(false);
                            stream.Flush();
                        }
                        stream.Close();
                        clientTCP.Close();
                    }
                    catch (Exception ex)
                    {
                        ExceptionHandler?.Invoke(this, ex);
                    }
                }
                listener.Server.Close();
            });
            return(IsListening);
        }
示例#4
0
        /// <summary>
        /// This is generic function which will send TCP command to specific IP, port and return the
        /// reply if required
        /// </summary>
        /// <param name="inputCommand">Commnad to be sent</param>
        /// <param name="isReplyRequired">Wait for reply?</param>
        /// <param name="txTimeout">Transmission timeout (ms)</param>
        /// <param name="rxTimeout">Receive timeout (ms)</param>
        /// <param name="connectionTimeout">Connection timeout (ms)</param>
        /// <param name="fireOnSent">Fires event on packet sent</param>
        /// <returns>Reply packet</returns>
        public async Task <ReplyPacket> SendTcpAsync(byte[] inputCommand, bool isReplyRequired = true, int txTimeout = defaultTimeout,
                                                     int rxTimeout = defaultTimeout, int connectionTimeout           = defaultConnectionTimeout, Action <bool> fireOnSent = null)
        {
            ReplyPacket replyPacket = new ReplyPacket();

            if (inputCommand is null)
            {
                replyPacket.Error = "Bytes to send is null";
                return(replyPacket);
            }

            using (TcpClient client = new TcpClient
            {
                ReceiveTimeout = rxTimeout,
                SendTimeout = txTimeout
            })
            {
                try
                {
                    IAsyncResult connectResult = client.BeginConnect(IP, Port, null, null);
                    replyPacket.IPSender   = IP;
                    replyPacket.PortSender = Port;
                    Task <bool> connectionTask = new Task <bool>(() =>
                                                                 connectResult.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(connectionTimeout)));
                    connectionTask.Start();

                    if (await connectionTask.ConfigureAwait(false))
                    {
                        using (NetworkStream stream = client.GetStream())
                        {
                            await stream.WriteAsync(inputCommand, 0, inputCommand.Length).ConfigureAwait(false);

                            stream.Flush();
                            replyPacket.IsSent = true;
                            fireOnSent?.Invoke(replyPacket.IsSent);
                            if (isReplyRequired)
                            {
                                //Reading The first byte for the sake of timeout
                                byte[] reply = new byte[1];
                                await stream.ReadAsync(reply, 0, 1).ConfigureAwait(false);

                                byte[] replyComplete = null;

                                //Reading rest of the bytes
                                if (stream.DataAvailable)
                                {
                                    replyComplete    = new byte[client.Available + 1];
                                    replyComplete[0] = reply[0];
                                    await stream.ReadAsync(replyComplete, 1, replyComplete.Length - 1).ConfigureAwait(false);
                                }

                                if (replyComplete != null)
                                {
                                    replyPacket.SetReply(replyComplete);
                                    replyPacket.IsSentAndReplyReceived = true;
                                }
                                else
                                {
                                    replyPacket.Error = "Unable to read from remote address";
                                }
                            }
                        }
                    }
                    else
                    {
                        fireOnSent?.Invoke(replyPacket.IsSent);
                        replyPacket.Error = "Connection TimeOut/Server Not Found";
                    }
                }
                catch (Exception ex)
                {
                    replyPacket.Error = ex.Message;
                }
            }

            return(replyPacket);
        }