Socket.Send, сервер получает много неверных MPacket

1
[Serializable]
public class Packet : ISerializable

Пакет - это использование моего класса для хранения данных, реализация ISerializable и всех необходимых конструкторов и функций, которые я читал из [ http://msdn.microsoft.com/en-us/library/ms182342.aspx]

[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
protected virtual void GetObjectData(SerializationInfo info, StreamingContext context)
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
private void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
protected Packet(SerializationInfo info, StreamingContext context)

Я помещаю свой пакет в DLL и ссылаюсь на него как на сервер, так и на клиентское приложение, чтобы они могли передавать пакет с помощью TcpListener (конвертировать в байт [] и отправлять, получать и конвертировать обратно)

Я протестировал сервер-клиент, отлично работающий с одним пакетом без отправки файла или меньше или равного 1 Мбайт. Это журнал сервера, когда он получил пакет с командой rename от клиента

[7174c67d-518f-4960-affe-d3bc67320d7e] Waiting for message
20/07/2014 13:03:48: {Rename} SUCCESS from 7174c67d-518f-4960-affe-d3bc67320d7e to NewName

Каждый пакет, он помещает максимальный размер байта в 1 мб в качестве данных части файла в байт [] msgFileData, а TcpListener получает максимум 2 Мб.

Проблема в том, что при отправке файла более чем 1 МБ я разбил этот файл на части, которые не более 1 мб на каждый, и только некоторые пакеты, полученные с правильным форматом, могут быть дебезируемыми, а некоторые - недопустимыми форматами пакетов. Немного времени это сработало и обычно показывает эту ошибку, поэтому я могу только загрузить, если я загружу ее в счастливый момент

        20/07/2014 13:03:48: {Rename} SUCCESS from 7174c67d-518f-4960-affe-d3bc67320d7e to NewName
    20/07/2014 13:03:48: [NewName] Waiting for message
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Uploaded 1/5 part of AMediumFile5mb.mp3 (Guid 40695b81-18b1-4329-bb00-344474458c47) from NewName
    20/07/2014 13:04:22: Uploaded 2/5 part of AMediumFile5mb.mp3 (Guid 40695b81-18b1-4329-bb00-344474458c47) from NewName
    20/07/2014 13:04:22: Error Packet: System.Runtime.Serialization.SerializationException: Binary stream '228' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization.
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
       at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
       at engine.converter.prjnameConverter.BinaryDeserializeObject[T](Byte[] serializedType) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 74
       at engine.converter.prjnameConverter.DeSerializeFromByteArray[T](Byte[] data) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 52
       at prjname.entity.Client.readResponsePacket(Byte[] data, Packet& Packet, Boolean& bValidPacket) in d:\Work\C#\Project\Work\prjname-Server\entity\Client.cs:line 154
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Uploaded 3/5 part of AMediumFile5mb.mp3 (Guid 40695b81-18b1-4329-bb00-344474458c47) from NewName
    20/07/2014 13:04:22: Error Packet: System.Runtime.Serialization.SerializationException: The input stream is not a valid binary format. The starting contents (in bytes) are: 30-0A-00-80-B2-98-3D-A7-FC-B4-41-FC-4F-02-81-03-8A ...
       at System.Runtime.Serialization.Formatters.Binary.SerializationHeaderRecord.Read(__BinaryParser input)
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadSerializationHeaderRecord()
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
       at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
       at engine.converter.prjnameConverter.BinaryDeserializeObject[T](Byte[] serializedType) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 74
       at engine.converter.prjnameConverter.DeSerializeFromByteArray[T](Byte[] data) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 52
       at prjname.entity.Client.readResponsePacket(Byte[] data, Packet& Packet, Boolean& bValidPacket) in d:\Work\C#\Project\Work\prjname-Server\entity\Client.cs:line 154
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Error Packet: System.Runtime.Serialization.SerializationException: The input stream is not a valid binary format. The starting contents (in bytes) are: 2B-01-83-40-2E-12-63-8F-C7-F6-89-B2-40-8C-CC-86-2E ...
       at System.Runtime.Serialization.Formatters.Binary.SerializationHeaderRecord.Read(__BinaryParser input)
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadSerializationHeaderRecord()
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
       at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
       at engine.converter.prjnameConverter.BinaryDeserializeObject[T](Byte[] serializedType) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 74
       at engine.converter.prjnameConverter.DeSerializeFromByteArray[T](Byte[] data) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 52
       at prjname.entity.Client.readResponsePacket(Byte[] data, Packet& Packet, Boolean& bValidPacket) in d:\Work\C#\Project\Work\prjname-Server\entity\Client.cs:line 154
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Error Packet: System.Runtime.Serialization.SerializationException: Binary stream '57' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization.
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
       at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
       at engine.converter.prjnameConverter.BinaryDeserializeObject[T](Byte[] serializedType) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 74
       at engine.converter.prjnameConverter.DeSerializeFromByteArray[T](Byte[] data) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 52
       at prjname.entity.Client.readResponsePacket(Byte[] data, Packet& Packet, Boolean& bValidPacket) in d:\Work\C#\Project\Work\prjname-Server\entity\Client.cs:line 154
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Error Packet: System.Runtime.Serialization.SerializationException: The input stream is not a valid binary format. The starting contents (in bytes) are: AA-01-17-58-02-01-40-C1-D1-51-10-38-29-A8-D5-68-C0 ...
       at System.Runtime.Serialization.Formatters.Binary.SerializationHeaderRecord.Read(__BinaryParser input)
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadSerializationHeaderRecord()
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
       at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
       at engine.converter.prjnameConverter.BinaryDeserializeObject[T](Byte[] serializedType) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 74
       at engine.converter.prjnameConverter.DeSerializeFromByteArray[T](Byte[] data) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 52
       at prjname.entity.Client.readResponsePacket(Byte[] data, Packet& Packet, Boolean& bValidPacket) in d:\Work\C#\Project\Work\prjname-Server\entity\Client.cs:line 154
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Error Packet: System.Runtime.Serialization.SerializationException: Binary stream '150' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization.
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
       at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
       at engine.converter.prjnameConverter.BinaryDeserializeObject[T](Byte[] serializedType) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 74
       at engine.converter.prjnameConverter.DeSerializeFromByteArray[T](Byte[] data) in d:\Work\C#\Project\Work\prjnameDll\converter\prjnameConverter.cs:line 52
       at prjname.entity.Client.readResponsePacket(Byte[] data, Packet& Packet, Boolean& bValidPacket) in d:\Work\C#\Project\Work\prjname-Server\entity\Client.cs:line 154
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Uploaded 4/5 part of AMediumFile5mb.mp3 (Guid 40695b81-18b1-4329-bb00-344474458c47) from NewName

Это должно быть что-то вроде этого

    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Uploaded 1/5 part of AMediumFile5mb.mp3 (Guid 40695b81-18b1-4329-bb00-344474458c47) from NewName
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Uploaded 2/5 part of AMediumFile5mb.mp3 (Guid 40695b81-18b1-4329-bb00-344474458c47) from NewName
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Uploaded 3/5 part of AMediumFile5mb.mp3 (Guid 40695b81-18b1-4329-bb00-344474458c47) from NewName
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Uploaded 4/5 part of AMediumFile5mb.mp3 (Guid 40695b81-18b1-4329-bb00-344474458c47) from NewName
    20/07/2014 13:04:22: [NewName] Waiting for message
    20/07/2014 13:04:22: Uploaded 5/5 part of AMediumFile5mb.mp3 (Guid 40695b81-18b1-4329-bb00-344474458c47) from NewName

********** Клиент *************

MainForm.cs

private void uploadFileToServerToolStripMenuItem_Click(object sender, EventArgs e)
    {
        OpenFileDialog dlgChooseUploadFile = new OpenFileDialog();
        dlgChooseUploadFile.Multiselect = false;
        /*some code*/
        if (dlgChooseUploadFile.ShowDialog() == DialogResult.OK)
        {
            /*some code*/
            string strFilePath = dlgChooseUploadFile.FileName;
            muUser.Upload(strFilePath); //muUser is class User
        }
    }

User.cs

    public void Upload(string strFilePath)
    {
        OnLockForm(true); // Disable MainForm while uploading
        UploadingForm uploader = new UploadingForm(strFilePath, this);//=> this: pass user as parameter to get user info like name, NetworkStream for sending request
        uploader.OnStopUpload += new UploadingForm.StopUpload((string strMessage)=>
        {
            OnLockForm(false);
            OnNotifyMessage(strMessage);
        });
        uploader.ShowDialog();
    }

UploadingForm.cs

public partial class UploadingForm : Form
{
    public delegate void StopUpload(string strMessage);
    public StopUpload OnStopUpload;
    private string mstrFilePath;
    private User sender;
    public UploadingForm(string strFilePath, User sender)
    {
        CheckForIllegalCrossThreadCalls = false;
        this.mstrFilePath = strFilePath;
        this.sender = sender;
        InitializeComponent();
    }

    private void UploadingForm_Shown(object sender, EventArgs e)
    {
        //some code
        ParepareUpload();
    }
    private void ParepareUpload()
    {
        Uploader uploader = new Uploader(mstrFilePath, sender);
        uploader.OnAPartUploaded += new Uploader.APartUploaded(()=>
        {
            /*some code but I disabled this delegate*/
        });
        uploader.OnUploadCanceled+= new Uploader.UploadCancel((string strReason)=>
        {
            OnStopUpload(strReason);
            this.Dispose();
        });
        uploader.OnUploadCompleted += new Uploader.UploadCompleted(() =>
        {
            OnStopUpload("Upload done");
            this.Dispose();
        });
        uploader.Begin();
    }

Uploader.cs

public class Uploader
{
    public delegate void UploadCompleted();
    public UploadCompleted OnUploadCompleted;
    public delegate void APartUploaded();
    public APartUploaded OnAPartUploaded;
    public delegate void UploadCancel(string strReason);
    public UploadCancel OnUploadCanceled;

    public string mstrFilePath { get; private set; }
    public string mUserName { get; private set; }
    public Guid mGuid { get; private set; }
    private NetworkStream mnetStream { get; set; }

    public Uploader(string strFilePath, User sender)
    {
        this.mGuid = Guid.NewGuid();
        this.mUserName = sender.mstrName;
        this.mstrFilePath = strFilePath;
        this.mnetStream = sender.netStream;
    }

    public void Begin()
    {
        /*some code*/
        BeginUploadFile();
    }

    private void BeginUploadFile()
    {
        try
        {
            string strFileName = Path.GetFileName(mstrFilePath);
            long lFileSize = new FileInfo(mstrFilePath).Length;
            byte iPartsCount = (byte)Math.Ceiling((decimal)lFileSize / engine.data.Packet.PACKET_MAXSIZE_UPLOADPART);
            for (byte i = 1; i <= iPartsCount; i++)
            {
                int numBytesToRead = Packet.PACKET_MAXSIZE_UPLOADPART;
                if (i == iPartsCount)
                {
                    numBytesToRead = (int)(lFileSize - ((i - 1) * Packet.PACKET_MAXSIZE_UPLOADPART));
                }
                sendPacket(Packet.CreatePFileUpload(strFileName, i, iPartsCount, readPartOfFile(Packet.PACKET_MAXSIZE_UPLOADPART * (i - 1), numBytesToRead), mGuid));
            }
            OnUploadCompleted();
        }
        catch (Exception ex)
        {
            OnUploadCanceled(ex.ToString());
        }
    }

    private object sync_readPartOfFile = new object();
    private byte[] readPartOfFile(int iByteFrom, int numBytesToRead)
    {
        lock (sync_readPartOfFile)
            try
            {
                using (FileStream fsSource = new FileStream(mstrFilePath, FileMode.Open, FileAccess.Read))
                {
                    fsSource.Seek(iByteFrom, SeekOrigin.Begin);
                    iByteFrom = 0;
                    long lEnd = fsSource.Length;
                    // Read the source file into a byte array.
                    byte[] bytes = new byte[numBytesToRead];
                    while (numBytesToRead > 0)
                    {
                        // Read may return anything from iByteFrom to numBytesToRead. 
                        int n = fsSource.Read(bytes, iByteFrom, numBytesToRead);

                        // Break when the end of the file is reached. 
                        if (n == 0)
                            break;

                        iByteFrom += n;
                        numBytesToRead -= n;
                    }
                    return bytes;
                }
            }
            catch
            {
                throw;
            }
    }

    private object sync_sendRequest = new object();
    private void sendPacket(Packet request)
    {
        lock (sync_sendRequest)
            try
            {
                request.pkOwner = mUserName;
                byte[] buffer = weHereConverter.SerizableObject(request);
                mnetStream.Write(buffer, 0, buffer.Length);
                mnetStream.Flush();
                //OnAPartUploaded(); /*tempolary disabled*/
            }
            catch (Exception)
            {
                throw;
            }
    }

******** ********** SERVER

ClientManager.cs//содержит список клиентов

    public void Listen(TcpClient tcpClient, string strName)
    {
        Client client = new Client(tcpClient, strName);
        client.OnNotifyDisconnect += new Client.NotifyDisconnect(ClientDisconnect);
        client.OnNotifyMessage += new Client.NotifyMessage(ClientMessage);
        client.OnNotifyReceivedData += new Client.NotifyReceivedData(ClientReceivedData);
        lock (sync_mlistClient)
        {
            Packet pkNotifySignIn = Packet.CreatePServerNotify("*ding* welcome...someone");
            foreach (Client c in mlistClient)
            {
                try
                {
                    c.send(pkNotifySignIn);
                }
                catch { }
            }
            mlistClient.Add(client);
        }
        client.BeginListen();
    }

    private void ClientReceivedData(Packet pkData, Client client)
    {
        if (pkData.isSCmd())
        {
            if (pkData.ScmdType == Command.SCMD_RENAME) // packet rename
            {
                /*some code*/
            }
            else if (pkData.ScmdType == Command.SCMD_FILEUPLOAD)
            {
                //new Thread(() => thread_UploadFile(pkData)).Start();
                thread_UploadFile(pkData);
            }
            else
            {
                /*some code*/
            }
        }
        else if (pkData.isMessage())
        {
            new Thread(() => ForwardMessageToClient(pkData, client)).Start();
        }
        else
        {
            /*some code*/
        }
    }

    // named thread but I call it like a normal method
    private void thread_UploadFile(Packet pkUploadData)
    {
        //new Thread(() => thread_OnUploadingFile(pkUploadData)).Start();
        thread_OnUploadingFile(pkUploadData);
    }

    private object sync_thread_OnUploadingFile = new object();
    private void thread_OnUploadingFile(Packet pkUploadData)
    {
        lock (sync_thread_OnUploadingFile)
        {
            FileUploadInfo uploadInfo = getFileUploadInfo(pkUploadData);
            if (uploadInfo.Fail) // reject packet, Fail marked as true when exception occured while writing to server hard disk
                return;
            try
            {
                File.WriteAllBytes(getUploadFilePart(pkUploadData.ScmdFileUploadGuid, pkUploadData.ScmdFileUploadPartNumber), pkUploadData.msgFileData);
            }
            catch (Exception ex)
            {
                /*server log*/MakeThreadNotifyMessage("Error while uploading part " + pkUploadData.ScmdFileUploadPartNumber + "/" + pkUploadData.ScmdFileUploadPartsCount + " of " + pkUploadData.ScmdFileUploadName + " (Guid " + pkUploadData.ScmdFileUploadGuid + ") from " + pkUploadData.pkOwner + "\r\n" + ex);
                uploadInfo.Fail = true;
            }
            finally
            {
                uploadInfo.OnAPartUploaded(); // increase count part uploaded in uploadInfo
                if (!uploadInfo.Complete)
                    /*server log*/MakeThreadNotifyMessage("Uploaded " + uploadInfo.CountPartsUploaded + "/" + pkUploadData.ScmdFileUploadPartsCount + " part of " + pkUploadData.ScmdFileUploadName + " (Guid " + pkUploadData.ScmdFileUploadGuid + ") from " + pkUploadData.pkOwner);
            }
        }
    }

    private Dictionary<Guid, FileUploadInfo> mdictFileUpload = new Dictionary<Guid, FileUploadInfo>();
    private object sync_mdictFileUpload = new object();
    private FileUploadInfo getFileUploadInfo(Packet pkUploadData)
    {
        lock (sync_mdictFileUpload)
        {
            FileUploadInfo result;
            if (!mdictFileUpload.TryGetValue(pkUploadData.ScmdFileUploadGuid, out result))
            {
                mdictFileUpload.Add(pkUploadData.ScmdFileUploadGuid, result = new FileUploadInfo(
                        pkUploadData.pkOwner, // uploader name
                        pkUploadData.ScmdFileUploadGuid, // file guid because I save on save like G-U-I-D-filename_partposition.part
                        pkUploadData.ScmdFileUploadName,  // file name
                        pkUploadData.ScmdFileUploadPartsCount // total parts count, ex: 5mb file will be splited into 5 parts
                        ));
                result.OnFileUploadCompleted += new FileUploadInfo.NotifyFileUploadCompleted(UploadCompleted);
            }
            return result;
        }
    }

FileUploadInfo.cs

    public class FileUploadInfo
{
    public delegate void NotifyFileUploadCompleted(FileUploadInfo uploadFile);
    public NotifyFileUploadCompleted OnFileUploadCompleted;
    public string UploaderName { get; private set; }
    public string FileName { get; private set; }
    public int PartsCount  { get; private set; }
    public Guid FileUploadGuid { get; private set; }
    private int _CountPartsUploaded = 0;
    private object sync_CountPartsUploaded = new object();
    public int CountPartsUploaded
    {
        private set
        {
            lock (sync_CountPartsUploaded)
                _CountPartsUploaded = value;
        }
        get
        {
            lock (sync_CountPartsUploaded)
                return _CountPartsUploaded;
        }
    }
    private bool _Fail = false;
    private object sync_Fail = new object();
    public bool Fail
    {
        get
        {
            lock (sync_Fail)
                return _Fail;
        }
        set
        {
            lock (sync_Fail)
                _Fail = value;
        }
    }
    private bool _Complete = false;
    private object sync_Complete = new object();
    public bool Complete
    {
        get
        {
            lock (sync_Complete)
                return _Complete;
        }
        set
        {
            lock (sync_Complete)
                _Complete = value;
        }
    }

    public FileUploadInfo(string UploaderName, Guid FileUploadGuid, string FileName, int PartsCount)
    {
        this.UploaderName = UploaderName;
        this.FileUploadGuid = FileUploadGuid;
        this.FileName = FileName;
        this.PartsCount = PartsCount;
    }

    public void OnAPartUploaded()
    {
        CountPartsUploaded += 1;
        if (CountPartsUploaded >= PartsCount)
        {
            OnFileUploadCompleted(this);
            Complete = true;
        }
    }
}

Client.cs

        byte[] message = new byte[2097152];
        int bytesRead;
        while (true)
        {
            bytesRead = 0;
            #region read client SPacket
            try
            {
                //blocks until a client sends a message
                /*server log*/OnNotifyMessage("[" + mstrName + "] Waiting for message");
                bytesRead = netStream.Read(message, 0, 2097152);
                if (bytesRead == 0)
                {
                    //the client has disconnected from the server
                    break;
                }
            }
            catch (Exception ex)
            {
                notifyError("Socket error", ex);
                break;
            }
            #endregion

            //message has successfully been received
            Packet pkRequestFromClient;
            Boolean bValidPacket;
            readRPacket(message, out pkRequestFromClient, out bValidPacket);
            if (bValidPacket)
            {
                processRequestPacket(pkRequestFromClient);
            }
            else
            {
                /*server log*/OnNotifyMessage("Error packet: "+ pkRequestFromClient.Exception);
            }

    private void readRPacket(byte[] data, out Packet packet, out bool bValidPacket)
    {
        try
        {
            packet = weHereConverter.DeSerializeFromByteArray<Packet>(data);
            bValidPacket = true;
        }
        catch(Exception ex)
        {
            packet = Packet.CreateErrorPacket(ex);
            bValidPacket = false;
        }
    }

Очень нужна помощь..

Спасибо за чтение!

  • 0
    покажите нам конец клиента (код разделения) и конец сервера (код объединения)
  • 0
    Я думаю это из-за потоков, да?
Показать ещё 9 комментариев
Теги:
sockets
serializable
send

2 ответа

1

После линии

bytesRead = netStream.Read(message, 0, 2097152);

вы не используете bytesRead чтобы определить, сколько байтов было получено. Вы предполагаете, что получено целое сообщение. TCP дает вам поток байтов, и он никак не сохраняет сообщения. Ваш код должен работать, даже если Read решает всегда читать только один байт.


В вашем коде есть много логики передачи. Невозможно ли использовать стандартизованный протокол для загрузки, например HTTP, FTP, WebServices, protobuf? Код сокета очень трудно понять. Лучший способ сделать это - избежать этого.

  • 0
    «Вы не используете bytesRead, чтобы определить, сколько байтов было получено. Вы предполагаете, что было получено все сообщение». Хорошо, я его записал. В моей проблеме, отправляет ли пакет, но не все ли данные, на сервер за один раз, так что мне делать, если он получает все данные моего пакета? «Разве нельзя использовать стандартизированный протокол для загрузки, такой как HTTP, FTP, WebServices, protobuf?» Нет, я хочу узнать, как использовать сокет с продуктом для моей совместной работы в будущем: D
  • 0
    Ваш вопрос немного неясен для меня. Вам как-то нужно убедиться, что вы передаете только целый пакет в код десериализации. Если вы используете protobuf в качестве проводного формата, вы можете просто передать NetworkStream в protobuf, и все будет обработано. Если вы настаиваете на том, чтобы сделать это вручную, добавьте префикс длины.
0

Это состояние гонки.

Проблема в том, что вы отправляете (например) файл размером 1,2 МБ, есть вероятность, что вторая часть 0.2 МБ будет обработана и записана в файл ПЕРЕД первой частью 1 МБ.

Таким образом, вы можете либо выполнять все операции как на client-, так и на стороне сервера синхронно или (я рекомендую это) очереди пакетов на стороне сервера, упорядочивать их по индексу и записывать их в правильном порядке.

Скажите мне, если вам нужна помощь в реализации

  • 0
    Я не совсем понимаю ваш ответ, но я перейду в очередь. Клиент (C) -> информация о файле -> Сервер (ы) S -> запросить часть 1 -> CC -> отправить часть 1 -> S / * loop * / Большое спасибо ^^ Я хочу проголосовать, но это требуется 15 репутации.
  • 0
    Мне действительно интересно узнать о результате. Держите меня в курсе, пожалуйста, и не обращайте внимания на голосование. Когда проблема решена, вы можете пометить мой ответ как правильный ответ :)
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню