gpt4 book ai didi

c# - 为什么文件不能通过 tcp 在 C# 中的客户端和 C 中的服务器之间正确传输(保存?)?

转载 作者:行者123 更新时间:2023-11-28 04:25:51 27 4
gpt4 key购买 nike

我已经在 C# 中设置了 TCP 客户端,在 C 中设置了服务器。当我要传输文件时,一些数据包丢失,文件没有正确保存。

我比较过我尝试传输的 PDF 文件,有一半的数据包没有保存,所以我无法在另一台电脑上打开它。

客户端代码:

public void SendFile(string file, string destPath = "C:\\")
{
int bufferSize = 1024;
byte[] filebuff = new byte[bufferSize];
string fileName = destPath + file;

//send to TcpServer request to send file
stream.Write(textToBytes("RECEIVEFILE"), 0, 11);
try
{
FileStream streamFile = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader binReader = new BinaryReader(streamFile);


//send file name to TcpServer
stream.Write(textToBytes(file), 0, file.Length);


//get file size
long filesize = streamFile.Length;

//send file size to TcpServer
//sendData(stream, BitConverter.GetBytes(filesize));

//if file doesn't exist
if (file == null)
{
Console.WriteLine("Error.");
}

//if file is empty
if (filesize == 0)
{
Console.WriteLine("File size: 0");
return;
}


int totalLength = Convert.ToInt32(filesize);

Console.WriteLine("Totallength: " + totalLength);
long numberOfPackets = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(streamFile.Length) / bufferSize));
int currentPacketLength;

for (int i = 0; i < numberOfPackets; i++)
{
if (filesize > bufferSize)
{
currentPacketLength = bufferSize;
totalLength = totalLength - currentPacketLength;
}
else
currentPacketLength = totalLength;

filebuff = new byte[currentPacketLength];
//streamFile.Read(filebuff, 0, currentPacketLength);
binReader.Read(filebuff, 0, currentPacketLength);


stream.Write(filebuff, 0, filebuff.Length);
}

streamFile.Close();
}
catch
{
Console.WriteLine("There's no file...");
}


}

public void DownloadFile(string fileName)
{
byte[] recBuffer = new byte[1024];
byte[] fileNameBytes;
long received = 0;
long receivedAll = 0;
byte[] fileData = new byte[1024];

stream.Write(textToBytes("SENDFILE"), 0, 8);
fileNameBytes = Encoding.UTF8.GetBytes(fileName);

stream.Write(fileNameBytes, 0, fileNameBytes.Length);
byte[] fileSizeBytes = new byte[4];
stream.Read(fileSizeBytes, 0, fileSizeBytes.Length);
int bytes = BitConverter.ToInt32(fileSizeBytes, 0);

Console.WriteLine("I'm downloading file...");

while (receivedAll < bytes)
{
received = stream.Read(fileData, 0, fileData.Length);
if (received < 0)
{
Console.WriteLine("Error");
break;
}
BinaryWriter bWrite = new BinaryWriter(File.Open("C:\\" + fileName, FileMode.Append));
bWrite.Write(fileData);
bWrite.Close();
receivedAll += received;

}

if(receivedAll == bytes)
{
Console.WriteLine("File downloaded successfuly.");
}
}

服务器代码:

void ReceiveFile(int client_socket)
{
const int buffsize = 1024;
char buff[buffsize];
long filesize, received = 0, receivedall;
char filenamechar[512];

std::string filename, fullFilename;
memset(filenamechar, 0, 512);
/*
if(recv(client_socket, filenamechar, 512, 0) != 512)
{
printf("Error - filename.\n");
return;
}

fullFilename = "/Users/xxx/" + std::string(filenamechar);

*
if(recv(client_socket, &filesize, sizeof(long), 0) != sizeof(long))
{
printf("Child process: error.\n");
return;
}*/

filesize = 331776;

std::fstream fileFromClient;

fullFilename = "/Users/xxx/sockets.pdf";

fileFromClient.open(fullFilename, std::ios::binary | std::ios::out);

receivedall = 0;
while (receivedall < filesize)
{
memset(buff, 0, 1024);
received = recv(client_socket, buff, 1024, 0);
if(received <= 0)
{
std::cout << "error" << std::endl;
break;
}
receivedall += received;

fileFromClient << buff;
fputs(buff, stdout);
}

fileFromClient.close();

std::cout << "\nreceivedall: " << receivedall << std::endl;
std::cout << "filesize: " << filesize << std::endl;
if(receivedall != filesize)
printf("Error\n");
else
printf("File saved successfuly\n");

}

void SendFile(int client_socket)
{
char path[512];
char fileName[512];
char fullFileName[512];
long fileLen, sent, sentAll, read;
struct stat fileinfo;
FILE* file;
unsigned char bufor[1024];

memset(path, 0, 512);
strcpy(path, "/Users/xxxx/");

if (recv(client_socket, fileName, 512, 0) <= 0)
{
printf("Child process: error\n");
return;
}

strcpy(fullFileName, strcat(path, fileName));
printf("Child process: client wants file: %s\n", fullFileName);


if (stat(fullFileName, &fileinfo) < 0)
{
printf("Child process: can't get file info\n");
return;
}

if (fileinfo.st_size == 0)
{
printf("Child process: file size: 0\n");
return;
}

fileLen = fileinfo.st_size;

if (send(client_socket, &fileLen, sizeof(long), 0) != sizeof(long))
{
printf("Child process: error\n");
return;
}

sentAll = 0;
file = fopen(fullFileName, "rb");
if (file == NULL)
{
printf("Error\n");
return;
}

while (sentAll < fileLen)
{
read = fread(bufor, 1, 1024, file);
sent = send(client_socket, bufor, read, 0);
if (read != sent)
break;
sentAll += sent;
printf("Child process: sent %ld bytes\n", sentAll);
}

if (sentAll == fileLen)
printf("Child process: file sent successfuly\n");
else
printf("Child process: error\n");
fclose(file);
return;
}

如何保证每个数据包都被妥善保存?

最佳答案

这一行有一个问题:

fileFromClient << buff;

这会写出buff的内容直到找到一个零字节。由于您正在传输二进制文件,因此您可以预期这些字节会很频繁。接收到的数据包的其余部分将不会被写入。

而不是使用 <<运算符,你应该使用

fileFromClient.write(buff, received);

关于c# - 为什么文件不能通过 tcp 在 C# 中的客户端和 C 中的服务器之间正确传输(保存?)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54370799/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com