c# - c#中的文件传输问题

标签 c# sockets tcp file-transfer

我正在使用 C# 传输文件。我用过this代码。问题是 .txt 文件等小文件可以正确传输,但不能正确传输图像、文档、pdf、ppt 等大文件。有时代码工作正常,但大多数时候它传输的数据量较少。

服务器代码:

Socket clientSock = sock.Accept();

byte[] clientData = new byte[1024 * 50000];
int receivedBytesLen = clientSock.Receive(clientData);
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);
bWrite.Close();
clientSock.Close();

客户端代码:

byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
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);
clientSock.Connect(ipEnd);
clientSock.Send(clientData);
clientSock.Close();

完整代码在上面的链接中给出。我也看过这个post但这没有帮助。

最佳答案

Sometimes code works fine but most of the times it transfers less amount of data.

这就是 Socket.Receive() 的本质,它并不总是返回发送给它的所有数据。

你必须做一个 Receive(clientData, 4, 0)首先接收指示 size 的字节,然后在循环中调用 Receive(clientData) 直到接收到 size 字节。但请注意,Receive(buffer[], length, offset) 重载与任何其他重载一样容易返回小于预期字节数的。所以你还必须在循环中调用它:

像这样:

// First receive the size
int sizeSize = 4; // Size of Int32 in bytes
int sizeOffset = 0;
var sizeBytes = new byte[sizeSize];
while (sizeOffset < sizeSize)
{
    sizeOffset += clientSocket.Receive(sizeBytes, sizeSize - sizeOffset, sizeOffset);
}

var size = BitConverter.ToInt32(sizeBytes, 0);

// Then receive the data
byte[] fileData = new byte[size];
byte[] clientData = new byte[8192];
int totalBytes = 0;

while (totalBytes < size)
{
    // This may return anything between 0 and 8192, even if not all sent data has been received yet. It may be in a buffer somewhere, waiting to be picked up. Check for 0, since that's when the client disconnects.
    int bytesReceived = clientSocket.Receive(clientData);

    // You now have received a chunk of data of bytesReceived length. Append it into the fileData array.
    Buffer.BlockCopy(clientData, 0, fileData, totalBytes, bytesReceived);

    totalBytes += bytesReceived;
}

关于c# - c#中的文件传输问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11905804/

相关文章:

c# - 除了使用访问者模式之外,还有其他方法可以在 C# 中使用变体吗?

c# - 使用带有 TestCase 属性的 nunit3-console.exe 进行参数化测试

java - PHP 卡在 socket_read 上

php - 通过HTTP下载文件时减少CPU使用率

c - c 中的 TCP 聊天无法正确读取/发送字符串

c# - 2个不同域值中的ANTLR3公共(public)值

c# - Span 标签直通在 CKEditor 中不起作用

java - 套接字编程。真的那么复杂吗?

c# - 如何使用 TcpClient 类在 WCF 中获取超时异常

ruby - 为什么 ruby​​ 无法在我的 Fedora 20 机器上打开 TCPSocket?