简体   繁体   中英

Receiving Data only from one machine instead of all machine over TCP/IP

Our Client have a dialysis machine which use Ethernet TCP/IP Protocol and data transfer protocol is XML.It automatically connects to the our computer system by using the configured IP address and port number and sends unsolicited data messages every 60 seconds to our system. Client send data as XML Data Stream. Now I need to store data in XML file. Below is my code.

Here now problem is, Client is sending data messages from four machines, However my code is capturing data from only one machine, Kindly suggest what I am missing here.

namespace NiproMI
{
    class NiproListener
    {
        public static void GetXMLStream()
        {
            TcpListener server = null;
            try
            {
                Int32 port = Int32.Parse(AppConfigValues.GetAppConfigValue("Port"));
                IPAddress localAddr = IPAddress.Parse(AppConfigValues.GetAppConfigValue("IPAddress"));
                server = new TcpListener(localAddr, port);
                server.Start();
                Byte[] bytes = new Byte[256];
                String data = null;
                while (true)
                {
                    TcpClient client = server.AcceptTcpClient();
                    NetworkStream stream = client.GetStream();
                    string fileName = "NiproMI_" + DateTime.Now.ToString("dd-MM-yyyy--HH-mm-ss-ffff") + ".xml";
                    int i;
                    while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {

                        data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                        WriteToFile(data, fileName);
                        if (data.Contains("</Rec>"))
                            {
                            MoveInputFile(fileName);
                            fileName = "NiproMI_" + DateTime.Now.ToString("dd-MM-yyyy--HH-mm-ss-ffff") + ".xml";
                            }
                    }
                }
            }
            catch (SocketException e)
            {
                MIEventLogs.WriteLog("SocketException: {0}" + e);
            }
            finally
            {
                server.Stop();
            }

        }
        public static void WriteToFile(string sMessage, string fileName)
        {
            try {
                DirectoryInfo logdirFile = new DirectoryInfo(System.Configuration.ConfigurationManager.AppSettings["XmlFilePath"].ToString());
                string filePath = logdirFile.FullName;
                if (File.Exists(Path.Combine(filePath, fileName)))
                {
                    StreamWriter sw = null;
                    //Open File
                    FileStream fs = File.Open(Path.Combine(filePath, fileName), FileMode.Append, FileAccess.Write);
                    // generate a file stream with UTF8 characters          
                    sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
                    sw.WriteLine(sMessage);
                    sw.Close();
                    sw = null;
                }
                else
                {
                    StreamWriter sw = null;
                    //Open File
                    FileStream fs = new FileStream(Path.Combine(filePath, fileName), FileMode.Create, FileAccess.Write);
                    // generate a file stream with UTF8 characters          
                    sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
                    sw.WriteLine(sMessage);
                    sw.Close();
                    sw = null;
                }
            }
            catch (Exception e)
            {
                MIEventLogs.WriteLog( e.ToString());
            }
        }
        private static void MoveInputFile(string sFileName)
        {
            string strSourceFullFileName = "";
            string strDestFullFilename = "";
            string movedFromFolder= AppConfigValues.GetAppConfigValue("XmlFilePath");
            string movedToFolder = AppConfigValues.GetAppConfigValue("InputPath");
            System.IO.DirectoryInfo objdestfolder = new System.IO.DirectoryInfo(movedToFolder);
            System.IO.DirectoryInfo getsourceFile = new System.IO.DirectoryInfo(movedFromFolder);
            string sourcePath = "";
            string DestPath = "";
            try
            {
                sourcePath = getsourceFile.FullName;

                if (sourcePath[sourcePath.Length - 1] != '\\')
                    sourcePath += "\\";

                if (File.Exists(sourcePath + sFileName))
                    strSourceFullFileName = sourcePath + sFileName;

                DestPath = objdestfolder.FullName;
                if (DestPath[DestPath.Length - 1] != '\\')
                    DestPath += "\\";

                strDestFullFilename = DestPath + sFileName;

                if ((File.Exists(strSourceFullFileName) == true) && (objdestfolder.Exists == true))
                {
                    if (File.Exists(strDestFullFilename))
                    {
                        File.Delete(strDestFullFilename);
                    }
                    File.Move(strSourceFullFileName, strDestFullFilename);
                    
                }
                else
                {
                    throw new System.ApplicationException("Invalid destination folder to move retry file.");
                }
            }
            catch (System.Exception ex)
            {
               
            }
            finally
            {

            }
        }
    }
}

You need to hand off the client to another thread or task while you wait for a new client.

I suggest you change this code to be fully asynchronous, using tasks and await . Something like this should work.

public static Task GetXMLStream(CancellationToken cancel)
{
    Int32 port = Int32.Parse(AppConfigValues.GetAppConfigValue("Port"));
    IPAddress localAddr = IPAddress.Parse(AppConfigValues.GetAppConfigValue("IPAddress"));
    using (var server = new TcpListener(localAddr, port))
    {
        server.Start();
        while (!cancel.IsCancellationRequested)
        {
            TcpClient client = await server.AcceptTcpClientAsync(cancel);
            Task.Run(async () => await ProcessClient(client, cancel));
        }
        server.Stop();
    }
}

private static async Task ProcessClient(TcpClient client, CancellationToken cancel)
{
    using (client)
    using (NetworkStream stream = client.GetStream())
    {
        try
        {
            await LoopClientStream(stream, cancel);
        }
        catch (OperationCanceledException)
        { //
        }
        catch (SocketException e)
        {
            MIEventLogs.WriteLog("SocketException: {0}" + e);
        }
    }
}

Your code that reads the stream and writes it to a file should also be fully asynchronous. I will leave that to you. Make sure you pass the CancellationToken to each asynchronous function.

You should also be aware that the stream may not return </Rec> in a single read, it may be split over separate reads. You may want to find a better way of tracking the end of each packet of data

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM