我正在尝试用C#(.NET)编写Socket编程。我已经参考了codeproject中的几个例子,但我的文件传输总是发送不完整的数据。
极小尺寸的数据工作正常,如1kB。但是较大的文件传输不完整,特别是图像。
这是我的客户端代码,它将文件发送到服务器。 clientData存储文件的二进制文件。
byte[] fileData = File.ReadAllBytes(filePath + fileName);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
curMsg = "Connection to server ...";
clientSock.Connect(ipEnd);
int count;
curMsg = "File sending...";
count = clientSock.Send(clientData);
MessageBox.Show(count+" "+clientData.Length);
curMsg = "Disconnecting...";
clientSock.Close();
虽然这是我的服务器代码,但它接收文件。
sock.Listen(100);
curMsg = "Running and waiting to receive file.";
Socket clientSock = sock.Accept();
byte[] clientData = new byte[1024 * 5000];
int receivedBytesLen = clientSock.Receive(clientData);
curMsg = "Receiving data...";
int fileNameLen = BitConverter.ToInt32(clientData, 0);
string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);
BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath +"/"+ fileName, FileMode.Append)); ;
bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
curMsg = "Saving file...";
bWrite.Close();
clientSock.Close();
有趣的是,当我在客户端的“发送”设置断点时,文件传输正常。我正在观察两端的字节数,并且当我使用断点时传输字节匹配,而当我没有接收到的字节低于客户端传输的字节时。
我做错了什么?
答案 0 :(得分:2)
你忘了实施协议了!要使用TCP,您必须设计并实现一个协议,该协议定义将发送的字节以及接收器如何识别消息或协议数据元素。你还没有做过这些。您的接收代码无法知道它是否已收到整个文件,因为没有协议可以告诉它,也没有任何代码来实现这样的协议。所以当然它错了 - 它没有办法让它正确。
如果receivedBytesLen
为1,那么您的代码就会失败。
答案 1 :(得分:1)
底层网络或TCP层可能并不总是将整个文件作为一个块发送。您可能会尝试执行while循环,直到您收到文件的确切/完整长度。
为此,您可能需要先发送文件的长度。
是的,这可能在调试模式下有效,但在运行时可能会有所不同。