-2

I am working with TCP/IP communication, in which my application is the client and the server. I checked NetworkStream and Asynchronous communication. While I am debugging the code I am able to get whole data without missing a single byte, but without debugging I miss some of the bytes. The same problem occurs when I place Thread.Sleep(1) after each receive operation.

    string ServeripAddress = "192.168.1.200";
    int PortNo = 8000;
    Socket clientSocket = null;
    byte[] breakBuffer;
    DateTime starttime;
    DateTime endtime;
    Boolean readflag;
    Boolean Firstflag;
    Thread th = null;

    byte[] readBuffer = new byte[1024];
    public delegate void DisplayStatus();
    public DisplayStatus StatusDelegate;
    string StatusMsg = string.Empty;

    int check = 0;
    string datalogPath = Application.StartupPath + "\\Datalog\\";
    string voicelogPath = Application.StartupPath + "\\Voicelog\\";
    string voicemsgPath = Application.StartupPath + "\\VoiceMsg\\";

    string status = string.Empty;
    List<string> listFileNames = new List<string>();
    int functionCode = 0;
    Queue<byte[]> bufferQueue = new Queue<byte[]>();
    byte[] finalbytes = new byte[1024];
    int numberOfBytesRead = 0;
    int lastPktlength = 0;
    int RemainLength = 0;
    bool FileDownloaded = false;
    long DownloadedLength = 0;
    long FileSize = 0;
    ArrayList BufList = new ArrayList();
    Boolean ReceiveBreaked = false;
    string fromDt = string.Empty;
    Boolean startedReceive = false;
    Thread thdUDPServer = null;
    AsyncCallback asyncCall = null;

    public Boolean Connect(string ServeripAddress, int port)
    {
        Boolean connect = false;
        try
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // Connect the socket to the remote endpoint.
            clientSocket.Connect(ServeripAddress, PortNo);

            if (clientSocket.Connected)
            {
                connect = true;
            }

        }
        catch (Exception ex)
        {
            Logger.Logger.WriteLog(ex);
        }
        return connect;
    }

    public ArrayList SendRequest(byte[] command, string frmD, ref string currentStatus, ref List<string> listFiles, int funCode)
    {
        try
        {
            Firstflag = true;
            fromDt = frmD;
            clientSocket.Send(command, command.Length, 0);
            functionCode = funCode;
            //Asynchronous receiving
            SetupRecieveCallback(clientSocket);
            readflag = true;
            BufList = new ArrayList();
            if (status == "Completed" && (functionCode != 1 && functionCode != 4 && functionCode != 7))
            {
                GenerateFiles(fromDt, ref BufList);
                //thdUDPServer = new Thread(new ThreadStart(() => GenerateFiles(fromDt, ref BufList)));
                //thdUDPServer.Start();
                status = "";
            }
            currentStatus = status;

        }
        catch (Exception ex)
        {
            Logger.Logger.WriteLog(ex);
        }
        return BufList;
    }

    private void GenerateFiles(string fromDt, ref  ArrayList BufList)
    {
        if (BufList.Count > 0 && (functionCode == 2 || functionCode == 3))
        {
            CreateWavFile(BufList, fromDt, "Voicelog");
        }
        else if (BufList.Count > 0 && (functionCode == 5))
        {
            CreateWavFile(BufList, fromDt, "VoiceMsg");
        }
        else if (BufList.Count > 0 && (functionCode == 8 || functionCode == 9))
        {
            CreateWavFile(BufList, fromDt, "Datalog");
        }
        else if (BufList.Count > 0 && functionCode == 3)
        {
            CreateAllDatesWavFile(BufList, listFileNames, "Voicelog");
        }
        else if (BufList.Count > 0 && functionCode == 6)
        {
            CreateAllDatesWavFile(BufList, listFileNames, "VoiceMsg");
        }

        // thdUDPServer.Abort();
    }

    private void SetupRecieveCallback(Socket soc)
    {
        try
        {
            readBuffer = new byte[soc.ReceiveBufferSize];
            asyncCall = new AsyncCallback(OnEthernetRecievedData);
            soc.BeginReceive(readBuffer, 0, readBuffer.Length, SocketFlags.None, asyncCall, soc);
        }
        catch (Exception ex)
        {
            Logger.Logger.WriteLog(ex);
        }
    }

    public void OnEthernetRecievedData(IAsyncResult ar)
    {
        Socket sock = (Socket)ar.AsyncState;

        try
        {
            Thread.Sleep(1);
            numberOfBytesRead = sock.EndReceive(ar);
            Array.Resize(ref readBuffer, (int)numberOfBytesRead);

            if (numberOfBytesRead > 0)
            {
                if (functionCode == 2 || functionCode == 5 || functionCode == 9)
                {

                    lastPktlength = 0;
                    DownloadFiles(readBuffer, ref status, numberOfBytesRead, ref  FileDownloaded, ref   DownloadedLength, ref   FileSize, ref  BufList);

                    if (status == "Fail")
                    {
                        // return BufList;
                        return;
                    }
                    else if (status == "Completed")
                    {
                        startedReceive = false;
                        thdUDPServer = new Thread(new ThreadStart(() => GenerateFiles(fromDt, ref BufList)));
                        thdUDPServer.Start();
                        return;
                    }

                }

            }
            //calling receive method
            SetupRecieveCallback(sock);

        }
        catch (Exception ex)
        {
            Logger.Logger.WriteLog(ex);
        }

    }

    private Boolean DownloadFiles(byte[] readBuffer, ref string status, int numberOfBytesRead, ref bool FileDownloaded, ref long DownloadedLength, ref  long FileSize, ref  ArrayList BufList)
    {
        Boolean completedStatus = false;
        int lastPktlength = 0;
        Boolean FileBreak = false;
        status = "";
        try
        {
            if (readBuffer[lastPktlength] == 76 && readBuffer[lastPktlength + 1] == 67 && readBuffer[lastPktlength + 2] == 0
          && readBuffer[lastPktlength + 3] == 16 && readBuffer[lastPktlength + 4] == 50 && readBuffer[lastPktlength + 5] == 48)
            {
                while (numberOfBytesRead > lastPktlength)
                {
                    NewMethod(ref status, readBuffer, numberOfBytesRead, ref lastPktlength, ref FileDownloaded, ref FileSize, ref finalbytes, BufList, ref  DownloadedLength);
                }
            }
            else
            {
                if (FileSize - DownloadedLength >= numberOfBytesRead)
                {
                    Array.Copy(readBuffer, 0, finalbytes, DownloadedLength, numberOfBytesRead);
                    DownloadedLength = DownloadedLength + numberOfBytesRead;
                }
                else
                {
                    Array.Copy(readBuffer, 0, finalbytes, DownloadedLength, FileSize - DownloadedLength);
                    lastPktlength = (int)(FileSize - DownloadedLength);
                    Logger.Logger.Messages(FileSize.ToString());
                    BufList.Add(finalbytes);

                    while (numberOfBytesRead > lastPktlength)
                    {
                        NewMethod(ref status, readBuffer, numberOfBytesRead, ref lastPktlength, ref FileDownloaded, ref FileSize, ref finalbytes, BufList, ref  DownloadedLength);
                    }
                }
            }



        }
        catch (Exception ex)
        {
            Logger.Logger.WriteLog(ex);
            status = "Fail";
            //return BufList;
        }
        return completedStatus;
    }

    private static void NewMethod(ref string status, byte[] readBuffer, int numberOfBytesRead, ref int lastPktlength, ref bool FileDownloaded, ref long FileSize, ref byte[] finalbytes, ArrayList BufList, ref long DownloadedLength)
    {
        try
        {
            int checkLength = lastPktlength + 16;

            for (int i = lastPktlength; i < readBuffer.Length; i++)
            {
                if ((readBuffer[lastPktlength] == 76 && readBuffer[lastPktlength + 1] == 67 && readBuffer[lastPktlength + 2] == 0
           && readBuffer[lastPktlength + 3] == 16 && readBuffer[lastPktlength + 4] == 50 && readBuffer[lastPktlength + 5] == 48))
                {
                    lastPktlength = i;
                    break;
                }
            }

            if ((readBuffer[lastPktlength] == 76 && readBuffer[lastPktlength + 1] == 67 && readBuffer[lastPktlength + 2] == 0
            && readBuffer[lastPktlength + 3] == 16 && readBuffer[lastPktlength + 4] == 50 && readBuffer[lastPktlength + 5] == 48)
                && (checkLength <= numberOfBytesRead)
                )
            {

                FileSize = 16 + (uint)((readBuffer[lastPktlength + 12] << 24) + (readBuffer[lastPktlength + 13] << 16) + (readBuffer[lastPktlength + 14] << 8) + (readBuffer[lastPktlength + 15]));
                string ffName = Encoding.ASCII.GetString(readBuffer, lastPktlength + 6, 6);

                finalbytes = new byte[FileSize];

                if ((numberOfBytesRead - lastPktlength) >= finalbytes.Length)
                {
                    if (FileSize > (numberOfBytesRead - lastPktlength))
                    {
                        Array.Copy(readBuffer, 0, finalbytes, (lastPktlength), FileSize - lastPktlength);
                    }
                    else
                    {
                        Array.Copy(readBuffer, lastPktlength, finalbytes, 0, FileSize);
                    }
                    lastPktlength = lastPktlength + (int)FileSize;
                    FileDownloaded = true;
                }
                else
                {
                    Array.Copy(readBuffer, lastPktlength, finalbytes, 0, numberOfBytesRead - lastPktlength);
                    DownloadedLength = numberOfBytesRead - lastPktlength;
                    lastPktlength = lastPktlength + (numberOfBytesRead - lastPktlength);
                }

                if (FileDownloaded)
                {
                    BufList.Add(finalbytes);
                    Logger.Logger.Messages(ffName + " : " + FileSize.ToString());
                    FileDownloaded = false;
                }
            }
            else if (readBuffer[lastPktlength] == 76 && readBuffer[lastPktlength + 1] == 67 && readBuffer[lastPktlength + 2] == 0
                       && readBuffer[lastPktlength + 3] == 6 && readBuffer[lastPktlength + 4] == 70 && readBuffer[lastPktlength + 5] == 48)
            {
                status = "Fail";
                //  return BufList;
            }

            else if (readBuffer[lastPktlength] == 76 && readBuffer[lastPktlength + 1] == 67 && readBuffer[lastPktlength + 2] == 0
                                          && readBuffer[lastPktlength + 3] == 6 && readBuffer[lastPktlength + 4] == 69 && readBuffer[lastPktlength + 5] == 48)
            {
                // BufList.Add(finalbytes);
                Logger.Logger.Messages("End time : " + DateTime.Now);
                status = "Completed";
                numberOfBytesRead = 0;
                lastPktlength = lastPktlength + 6;
            }
            else //if ((numberOfBytesRead - lastPktlength) < 16)                           
            {

            }
        }
        catch (Exception ex)
        {
            Logger.Logger.WriteLog(ex);
        }
    }

    public void CreateAllDatesWavFile(ArrayList listBuffer, List<string> listFileNames, string fileType)
    {
        try
        {
            for (int i = 0; i < listBuffer.Count; i++)
            {
                string wavPath = string.Empty;
                string folderName = listFileNames[i].Substring(0, 6).ToString();
                string fileName = listFileNames[i].Substring(6, 6).ToString();

                if (fileType == "Voicelog")
                {
                    if (!Directory.Exists(voicelogPath + folderName))
                    {
                        Directory.CreateDirectory(voicelogPath + folderName);
                    }

                    wavPath = voicelogPath + folderName + "\\" + fileName + ".Wav";
                    // wavPath = voicelogPath + datePath + "\\" + listFileNames[i].ToString() + ".Mp4";
                }
                else if (fileType == "VoiceMsg")
                {
                    if (!Directory.Exists(voicemsgPath + folderName))
                    {
                        Directory.CreateDirectory(voicemsgPath + folderName);
                    }
                    wavPath = voicemsgPath + folderName + "\\" + fileName + ".Wav";
                }

                FileStream stream;
                if (!File.Exists(wavPath))
                {
                    stream = new FileStream(wavPath, FileMode.Create, FileAccess.ReadWrite);
                }
                else
                {
                    stream = new FileStream(wavPath, FileMode.Open, FileAccess.ReadWrite);
                }
                stream.Close();

                File.WriteAllBytes(wavPath, (byte[])listBuffer[i]);
            }
        }
        catch (Exception ex)
        {
            Logger.Logger.WriteLog(ex);
        }
    }

    public void CreateWavFile(ArrayList listBuffer, string fromDate, string fileType)
    {
        try
        {
            for (int i = 0; i < listBuffer.Count; i++)
            {
                string wavPath = string.Empty;
                string datePath = fromDate;
                string fileName = Encoding.ASCII.GetString((byte[])listBuffer[i], 6, 6);

                if (fileType == "Voicelog")
                {
                    if (!Directory.Exists(voicelogPath + datePath))
                    {
                        Directory.CreateDirectory(voicelogPath + datePath);
                    }

                    wavPath = voicelogPath + datePath + "\\" + fileName + ".Wav";

                    // wavPath = voicelogPath + datePath + "\\" + listFileNames[i].ToString() + ".Mp4";
                }
                else if (fileType == "VoiceMsg")
                {
                    if (!Directory.Exists(voicemsgPath + datePath))
                    {
                        Directory.CreateDirectory(voicemsgPath + datePath);
                    }
                    wavPath = voicemsgPath + datePath + "\\" + fileName + ".Wav";
                }
                else if (fileType == "Datalog")
                {
                    wavPath = Application.StartupPath + "\\Datalog\\" + fileName + ".txt";
                }

                FileStream stream;
                if (!File.Exists(wavPath))
                {
                    stream = new FileStream(wavPath, FileMode.Create, FileAccess.ReadWrite);
                }
                else
                {
                    stream = new FileStream(wavPath, FileMode.Open, FileAccess.ReadWrite);
                }
                stream.Close();

                byte[] startOffile = new byte[16];
                Array.Copy((byte[])listBuffer[i], 0, startOffile, 0, 16);
                long sizef = (uint)((startOffile[12] << 24) + (startOffile[13] << 16) + (startOffile[14] << 8) + (startOffile[15]));

                byte[] fileArray = new byte[sizef];
                Array.Copy((byte[])listBuffer[i], 16, fileArray, 0, sizef);

                File.WriteAllBytes(wavPath, fileArray);
            }
        }
        catch (Exception ex)
        {
            Logger.Logger.WriteLog(ex);
        }
    }

Please help me on this Issue.

  • 2
    It would be very helpful if you show us your code. – John Källén Jan 02 '16 at 12:10
  • and btw if you using async i.e read/write `async` then why mould you use `Thread.Sleep` in between the calls? – Abdullah Saleem Jan 02 '16 at 12:21
  • Here I am using Asynchronous call only for Reading the data. I am downloading the data from embeded application to client side(i.e. our applicaton) – swati pujari Jan 02 '16 at 12:34
  • 2
    Try searching. Or rather, try reading about how sockets work before trying to use them. You need a framing protocol, and my guess is that you ignore the value returned by `Read()`. You're assuming one `Send()` has one corresponding `Receive()`, which is false. See [Why does my client socket not receive what my server socket sends?](http://stackoverflow.com/questions/23713664/why-does-my-client-socket-not-receive-what-my-server-socket-sends), and start at [Beej's Guide to Network Programming](https://beej.us/guide/bgnet/output/html/multipage/index.html) – CodeCaster Jan 02 '16 at 12:39

1 Answers1

0

The main reason of network issues is included inside the application architecture and the management of threading inside it. So, if you are losing information when the application is free (i.e. without debagging) while you are good in debagging mode, the best reason for that might be use of break points. In any debagging tool if a break point got hit on a thread then all thread is got freeze and process resume as your start executing. Sometimes, this automatically solves some sync problem as all thread got a time to freeze and start. But, on the other hand the problem keeps there in actual running. This problem will be broader as your programming logic gets more and more bigger.

Possible Remedies

  1. Make sure you are using only a single thread for writing and a single thread for reading stream. Even read and write can be made on single thread also.

  2. Make sure you are using flush stream method after each successful write.

  3. Make sure your reader thread is all time running and writer will awake at required.
  4. Most importantly, make sure, the process of reading is exactly the opposite of writing process.

If still the problem is not solved, then show the code for better suggestion and understandings.

  • Here I removed all threads and I am sending request to server and calling Asynchronous receiving upto the end of Data. At the end I am checking last End Bytes and Generating file, but all data not received. But in debug mode I am able to receive all data. Please help me out, I tried this using network stream also, but getting same problem – swati pujari Jan 02 '16 at 12:52
  • Can you tell me specifically what are the position of the bytes you lost? – user3539722 Jan 02 '16 at 13:00