C#.NET TCP / IP客户端通信缺少数据

时间:2016-01-02 12:07:32

标签: c# tcp

我正在使用TCP / IP通信,其中我的应用程序是客户端和服务器。我检查了NetworkStream和异步通信。当我调试代码时,我能够在不丢失单个字节的情况下获得整个数据,但是没有调试我错过了一些字节。在每次接收操作后放置Thread.Sleep(1)时会出现同样的问题。

    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);
        }
    }

请帮我解决这个问题。

1 个答案:

答案 0 :(得分:0)

网络问题的主要原因包括在应用程序体系结构和其中的线程管理中。因此,如果您在应用程序空闲时(即没有取消标记)丢失信息,而您在擅长debagging模式时,最好的原因可能是使用断点。在任何debagging工具中,如果一个断点被一个线程击中,那么所有线程都会被冻结,并且当你开始执行时,进程恢复。有时,这会自动解决一些同步问题,因为所有线程都有时间冻结并启动。但是,另一方面,问题仍然存在于实际运行中。随着编程逻辑变得越来越大,这个问题会越来越广泛。

可能的补救措施

  1. 确保您只使用单线程进行编写,并使用单线程进行阅读。甚至可以在单线程上进行读写。

  2. 确保在每次成功写入后使用 flush stream 方法。

  3. 确保您的读者线程一直在运行,并且作者将在需要时醒来。
  4. 最重要的是,确保,阅读过程正好与写作过程相反
  5. 如果问题仍未解决,请显示代码以获得更好的建议和理解。