none
TCP IP Listener Problem Received data form client and store in SQL database RRS feed

  • Question

  • hi i am new in filed of programming . 

    I am create a TCPIP Listener to received a  data from Medical Device and store in text file . for this purpose  create TCP IP Lister   Listener run successfully and devise connect successfully with my server .

    As per document of devise . 

    When we try to send data from medical device to server . 

    medical  devise  send : ENQ

    Server Reply  : ACK 

    Then Medical Devise next frame to server look like this : H|\^&|||00-99100^00-00^^^^medical-100 01^12345678||||||||E1394-97

    Server received this frame and safe it  and send ACK again   to client   for next frame . 

    Client Send Next Frame . O|1||^^ 12RT5ABCDE^B|^^^^WdC\^^^^RdC\^^^^HwB\ ^^^^HuT\ ^^^^MTV\^^^^MCH\^^^^MCHC\^^^^PLT\^^^^W-SCR\ ^^^^W-MCR\^^^^W-LCR\^^^^W-SCC\^^^^W-UNC\^^^^W\ ^^^^RFW\^^^^RYW-CV\^^^^PFW\^^^^MYV\^^^^Q-LCR |||||||N||||||||||||||F

    <cr>Server send again  ACK to Client  till Client send EOT  when server received EOT from Client save data in text file and clear the  memory  </cr>

    <cr>and server ready for next Record </cr>

    namespace ServerOK
    {
    
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    string HostName = Dns.GetHostName();
    
                    // This line is obsolet
                    String MyIP = Dns.GetHostByName(HostName).AddressList[0].ToString();
                    IPAddress IPAd = IPAddress.Parse(MyIP);
    
    
                    IPAddress ipAd = IPAddress.Parse(MyIP); //use local m/c IP address, and use the same in the client
                                                            /* Initializes the Listener */
                    TcpListener myList = new TcpListener(ipAd, 8001);
                    /* Start Listeneting at the specified port */
                    myList.Start();
                    Console.WriteLine("The server is running at port 8001...");
                    Console.WriteLine("The local End point is :" + myList.LocalEndpoint);
                    Console.WriteLine("Waiting for a connection.....");
                    while (true)
                    {
                        Socket s = myList.AcceptSocket(); // This line is blocking
                        Task connectionTask = new Task(() =>
                        {
                            Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
                            byte[] b = new byte[100];
                            int k = s.Receive(b);
                            Console.WriteLine("Recieved...");
                            for (int i = 0; i < k; i++)
                                Console.Write(Convert.ToChar(b[i]));
                            ASCIIEncoding asen = new ASCIIEncoding();
                            s.Send(asen.GetBytes(""));
                            //=========================
    
                            string path = @"D:\MyTest.txt";
    
                            // This text is added only once to the file.
                            if (!File.Exists(path))
                            {
                                // Create a file to write to.
                                string createText = k + Environment.NewLine;
                                File.WriteAllText(path, createText);
                            }
    
                            // This text is always added, making the file longer over time
                            // if it is not deleted.
                            string appendText = k + Environment.NewLine;
                            File.AppendAllText(path, appendText);
    
    
    
                            //=========================
    
    
    
    
                            Console.WriteLine("\n  ACK");
    
                            /* clean up */
                            s.Close();
                        });
                        connectionTask.Start();
                    }
                    myList.Stop(); // You will never reach this line
                    Console.ReadKey();
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error..... " + e.StackTrace);
                }
    
                
    
            }
    
        }
    }

    <cr>Kindly advise is what changes should be required in my server code .</cr>



    • Edited by Skhan07 Monday, February 10, 2020 6:16 AM Change Question
    Tuesday, February 4, 2020 8:01 AM

All replies

  • Hi Skhan07,
    Based on your description,it is recommend to debug it firstly.
    For Server,please refer to the following code example.

    class Program
        {
            static readonly object _lock = new object();
            static readonly Dictionary<int, TcpClient> list_clients = new Dictionary<int, TcpClient>();
    
    
            static void Main(string[] args)
            {
                int count = 1;
    
                TcpListener ServerSocket = new TcpListener(IPAddress.Any, 5000);
                ServerSocket.Start();
    
                while (true)
                {
                    TcpClient client = ServerSocket.AcceptTcpClient();
                    lock (_lock) list_clients.Add(count, client);
                    Console.WriteLine("Someone connected!!");
    
                    Thread t = new Thread(handle_clients);
                    t.Start(count);
                    count++;
                }
    
            }
    
            public static void handle_clients(object o)
            {
                int id = (int)o;
                TcpClient client;
    
                lock (_lock) client = list_clients[id];
    
                while (true)
                {
                    NetworkStream stream = client.GetStream();
                    byte[] buffer = new byte[1024];
                    int byte_count = stream.Read(buffer, 0, buffer.Length);
    
                    if (byte_count == 0)
                    {
                        break;
                    }
    
                    string data = Encoding.ASCII.GetString(buffer, 0, byte_count);
                    broadcast(data);
                    Console.WriteLine(data);
                }
    
                lock (_lock) list_clients.Remove(id);
                client.Client.Shutdown(SocketShutdown.Both);
                client.Close();
            }
    
            public static void broadcast(string data)
            {
                byte[] buffer = Encoding.ASCII.GetBytes(data + Environment.NewLine);
    
                lock (_lock)
                {
                    foreach (TcpClient c in list_clients.Values)
                    {
                        NetworkStream stream = c.GetStream();
    
                        stream.Write(buffer, 0, buffer.Length);
                    }
                }
            }
        }

    More details you can refer to this link.
    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, February 5, 2020 7:56 AM
  • Hi SKHan07

    I'm pretty unclear whether your post represents a problem with code you actually wrote or whether it's a misunderstanding about how TCP works when the protocol is supplied by a Socket, which is an operating system software convention.

    TCP ACK packets are part of the underlying TCP Protocol.  Unless you've set up your TCPListener's underlying socket using socket options that allow or require you to provide your own protocol headers, which I think you can only do with a RAW socket in Admin mode (if you can even do it at all with Windows 10), you'll never have access to ACK.  It's not a string "ACK" and throwing in a newline "\n" makes little or no sense at all.  A TCP ACK packet is a header composed of raw binary data.  These packets will be returned on the datastream automatically by the Socket implementation as needed.  You will not only never need to send one but you won't be able to inject any data into the network except your own application-specific data payload.  Meaning you can't send ACK packets through a TCPListener or TCPClient or even a Socket using ProtocolType.TCP

    Maybe your ENQ and ACK strings are part of the device's own proprietary protocol, which would be subordinate to TCP, not part of TCP.

    I think anyone who could help you would be more able to do so if you actually explained what you're doing, what device you're connecting to (and its connection type, whether it's RS232 or USB or e-SATA or whatever), and you should provide real reference links to the documentation you've quoted, which is certainly not TCP documentation. 

    If this were real TCP documentation for example, it would not advise you to "continue sending ACK until you receive an End of Transfer signal" because an ACK in TCP is only used to let the other end know that it received data - this is part and parcel with TCP being a "reliable" protocol compared to UDP where packets are just thrown willy-nilly across the wire without any cross-talk indicating that the target-end received anything at all from the sender.  In real TCP documentation, you send exactly 1 ACK packet for exactly 1 received packet.

    Wednesday, February 5, 2020 9:00 PM
  • Hi 

    i am using TCPIP connection. and my devise also connected with my server on  TCPIP 

    Successfully devise connect my server . 

    After Connect Client Send ENQ to Serve 

    string enq = char.ConvertFromUtf32(5);

    and server send  ACK to Client 

     string ack = char.ConvertFromUtf32(6);

    When Client Received ACK

    Send next (Data to Server ) Frame  to Server and waiting for next Next ACK 

    this process continue till when client send EOT  When Server received EOT From the client server close this connection and ready for another transaction  from client. 

    2020-02-06 16:59:36 S(1){<ENQ>}
    2020-02-06 16:59:36 R(1){<ACK>}
    2020-02-06 16:59:36 S(29){<STX>1H|\^&|||LIS|||||||P|1<CR><ETX>A2<CR><LF>}

    Full Frame .

    2020-01-14 13:59:50 R(1){<ACK>}
    2020-01-14 13:59:50 S(29){<STX>1H|\^&|||LIS|||||||P|1<CR><ETX>A2<CR><LF>}
    2020-01-14 13:59:50 R(1){<ACK>}
    2020-01-14 13:59:50 S(110){<STX>2P|1|0050007|||Test CD^Test.||19700605|M|||||001^sunny|||159.9|55.3|||||||OP|MED^MEDICAL|||||||19990306<CR><ETX>7D<CR><LF>}
    2020-01-14 13:59:50 R(1){<ACK>}
    2020-01-14 13:59:50 S(33){<STX>3C|1||<CR><ETX>D5<CR><LF>}
    2020-01-14 13:59:51 R(1){<ACK>}
    2020-01-14 13:59:51 S(91){<STX>4OBR|1|82000011||HGB^HGB|||202001141359||50||N||^|202001141359|018^33|||||||||001|||<CR><ETX>AF<CR><LF>}
    2020-01-14 13:59:52 S(1){<EOT>}

    ===================================================

    My Question  how to save these data on variable and  text file . 

    -------------------------------------------------------

    Thursday, February 6, 2020 12:28 PM
  • // Standard usings
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    // Usings specific to this implementation
    using System.IO;
    using System.Reflection;
    
    namespace ConsoleApplication
    {
        public static class Program
        {
            // This will be the same directory where the executable runs from - make sure it's accessible 
            // per Directory/File Security settings
            //
            // Path is a member of System.IO while Assembly comes from System.Reflection.
            static string appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    
            // This is the path the log will be written to.  The file will be networkLog.txt 
            // and the directory will be the same as wherever the program.exe file resides
            static string logPath = appPath + @"\networkLog.txt";
    
            /// <summary>
            /// A Queue is a First-In-First-Out (FIFO) collection.
            /// </summary>
            static Queue<string> NetworkIO = new Queue<string>();
    
            // Pass a text CODEC as found in System.Text.Encoding, or pass null 
            // to default to UTF8
            static void WriteLog(Encoding e, string message)
            {
                if (e == null)
                {
                    e = Encoding.UTF8;
                }
    
                // FileMode.OpenOrCreate will create the file specified by logPath if it doesn't already exist, or open it 
                // if it does exist.
                FileStream fs = new FileStream(Program.logPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
                // This ensures the FileStream begins writing at the end of the logfile, if it already existed.
                fs.Position = fs.Length;
    
                // Encode your logged message
                Byte[] bfr = e.GetBytes(message);
                // Write to filestream buffers
                fs.Write(bfr, 0, bfr.Length);
                // Dispose of the buffer.
                bfr = null;
    
                // Always flush before closing a filestream.  This ensures that all data is written to disk or network or 
                // wherever the IO.Stream is pushing data to, before your program can continue.
                fs.Flush();
                // Always close before disposing a filestream.  This ensures permissions are released.
                fs.Close();
                fs.Dispose();
            }
    
            public static int Main(string[] args)
            {
                int r = 0;
    
    
                string enq = char.ConvertFromUtf32(5);
                // Encqueue the enq before transmission or upon receipt.
                NetworkIO.Enqueue(enq);
    
                // When you dequeue to transmit or do stuff with your ENQ packet you should log it at that time - your scenario 
                // may prefer logging before network transmission, or it may prefer logging after.  
                //
                // You may also want to use a secondary Queue instance to ensure that ENQ packets aren't logged until or unless 
                // the other side sends an ACK
    
                // Sending a null encoding will default to UTF8 per the code in the WriteLog function.
                Program.WriteLog(null, enq);
    
                string ack = char.ConvertFromUtf32(6);
                // Enqueue the ack before transmission or on receipt of it.
                NetworkIO.Enqueue(enq);
    
                // Dequeue to do stuff with your ACK packet and log it - see caveats/addendums above and apply them here too
                Program.WriteLog(null, ack);
    
                return r;
            }
        }
    }


    • Edited by Andrew B. Painter Thursday, February 6, 2020 4:01 PM if (e!=null) is wrong - fixed to if (e==null) in WriteLog function
    Thursday, February 6, 2020 3:36 PM
  • Thanks for your fine quick reply . 

    My Problem is date . TCP IP Listener and Client Successfully . but i am not handel the data in  TCP IP Listener  

    For Example . 

    Step .1 

    TCP IP Listner  Run Successfully .   and Client  connect Successfully to Server . Connection establish successfully .

    Step .2

    Client Send  ENQ To Server  (enq = char.ConvertFromUtf32(5)

    Server Send  ACK To Client (ACK = char.ConvertFromUtf32(6)

    When client Received Ack from Server they send data frame to Server like .

    2020-01-14 10:09:24 S(29){<STX>1H|\^&|||LIS|||||||P|1<CR><ETX>A2<CR><LF>}

    Step .3

    This data show in console and save in Variable . 

    and server send agin  ACK To Client.

    Client received ACK and send next part of data Like  

    2020-01-14 10:09:25 S(87){<STX>4OBR|1|82000009||C^C|||202001141009||50||N||^|202001141009|018^33|||||||||001|||<CR><ETX>8A<CR><LF>}

    Server received this data and append in Variable already store previous data received from client and send again ACK to Client 

    Step 4

    Client received ACK and Send (EOT)  (EOT = char.ConvertFromUtf32(4)  

    EOT means data complete . and server move to data in text file and clear the variable memory . 

    Step 5 

    and this process start again when ever client send data . 

    Please help me to develop TCPIP Listener to perform this type of functionality  .

    Thanks 

      

     

    Friday, February 7, 2020 4:46 AM
  • any reply
    Saturday, February 8, 2020 1:20 PM
  • any reply
    You keep changing the question every time you get an answer.  I'm no longer sure what the question is.
    Saturday, February 8, 2020 5:05 PM