问题描述:

[Serializable]

public class Packet : ISerializable

Packet is my class use for holding data, implemented ISerializable and all needed constructor and functions I read from

[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)

I put my Packet inside a dll and reference it in both server and client application so they can transfer Packet using TcpListener (convert to byte[] and send, received and convert back)

I tested server-client worked perfectly with single Packet without sending file or less-or-equals 1mb file.

This is server log when it received a Packet with rename command from client

[7174c67d-518f-4960-affe-d3bc67320d7e] Waiting for message

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

Each Packet, it put maximum 1mb length byte array as file part's data on byte[] msgFileData property and TcpListener receive maximum 2mb.

The problem is when sending a more-than-1mb file, I splited that file into parts which maximum 1mb per-each and only some Packets received with correct format, can deserizable and some are Invalid Packet format. A little time it worked and usually show this error so I can only upload if I upload it in a lucky moment

 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

It has to be something like this

 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


**********Client*************

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 // hold list of clients

 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's 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's 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;

}

}

Really need help..

Thanks for read!

网友答案:

After the line

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

you are not using bytesRead to determine how many bytes were received. You assume that an entire message was received. TCP gives you a stream of bytes and it does not preserve messages in any way. Your code must function even if Read decides to always read just one byte.


There is a lot of transfer logic in your code. Is it not possible to use a standardized protocol for uploading, such as HTTP, FTP, WebServices, protobuf? Socket code is very hard to get right. Best way to do it is to avoid it.

网友答案:

This is a race condition.

The problem is when you send (for example) a 1.2MB file, there is chance that the second 0.2MB part will be processed and written to the file BEFORE the first 1MB part.

So you can either execute all the operations on both the client- and server-sides synchronously, or (I recommend this) queue the packets on the server side, order them ascending by index and then write them in the correct order.

Tell me if you need help implementing

相关阅读:
Top