套接字文件传输在C#中发送不完整的文件

时间:2012-01-26 10:30:57

标签: c# .net sockets tcpclient file-transfer

我正在尝试用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();

有趣的是,当我在客户端的“发送”设置断点时,文件传输正常。我正在观察两端的字节数,并且当我使用断点时传输字节匹配,而当我没有接收到的字节低于客户端传输的字节时。

我做错了什么?

2 个答案:

答案 0 :(得分:2)

你忘了实施协议了!要使用TCP,您必须设计并实现一个协议,该协议定义将发送的字节以及接收器如何识别消息或协议数据元素。你还没有做过这些。您的接收代码无法知道它是否已收到整个文件,因为没有协议可以告诉它,也没有任何代码来实现这样的协议。所以当然它错了 - 它没有办法让它正确。

如果receivedBytesLen为1,那么您的代码就会失败。

答案 1 :(得分:1)

底层网络或TCP层可能并不总是将整个文件作为一个块发送。您可能会尝试执行while循环,直到您收到文件的确切/完整长度。

为此,您可能需要先发送文件的长度。

是的,这可能在调试模式下有效,但在运行时可能会有所不同。