【发布时间】:2019-05-21 11:31:16
【问题描述】:
我正在使用 TCP 服务器/客户端 C 应用程序将文件从服务器发送到客户端。文件必须分部分发送(一个连接一个部分)。我成功地将文件从服务器发送到客户端,这不是问题。问题在于每个连接的一个部分,要发送正确的部分。我正在使用 fseek() 来查找整个文件的大小并将其除以 4。这就是我想要发送给客户端的块的大小。问题仍然存在,因为我得到的块比我实际预期的要多。
// Retrieve file size
fSize = fileSize(filePtr);
// How much bytes to send
if (fSize >= 4)
{
leftToSend = fSize / SEND_DENOM;
}
else
{
leftToSend = fSize;
}
int fpOffset = leftToSend * (partToSend - 1);
fseek(filePtr, fpOffset, SEEK_SET);
int i = 0;
char cFromFile;
while(leftToSend != 0 || feof(filePtr))
{
cFromFile = fgetc(filePtr);
dataBuffer[i++] = cFromFile;
leftToSend--;
bytesSent++;
if (strlen(dataBuffer) == (BUFFER_SIZE - 1) || leftToSend == 0)
{
// Send message to client
iResult = sendto(clientSocket,
dataBuffer,
strlen(dataBuffer),
0,
(SOCKADDR *)&clientAddress,
sizeof(clientAddress));
if (iResult == SOCKET_ERROR)
{
printf("sendto failed with error: %d\n", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
ExitThread(100);
}
// Set whole buffer to zero
memset(dataBuffer, 0, BUFFER_SIZE);
i = 0;
}
}
查找文件大小功能:
unsigned long long int fileSize (FILE* filePtr)
{
unsigned long long int fSize = 0;
fseek(filePtr, 0, SEEK_END);
fSize = ftell(filePtr);
rewind(filePtr);
return fSize;
}
示例(它的外观):
这是个问题……
块 - 这个_
块 - is_a_
块 - 问题
块 - em...
这是我得到的:
块 - This_is_a
块 - is_a_prob
块 - 问题..
块 - em...
其中_代表空格
【问题讨论】:
-
到目前为止,我无法从快速疏忽中识别出任何明显的警报。请发布 sendto 函数或至少解释它的作用。
-
您没有将字符串终止符写入
dataBuffer[ ],因此strlen将失败。还有|| feof(filePtr)是干什么用的?如果您已经有读取错误,为什么还要永远阅读?您知道文件的大小,因此只需计算字节数。 -
@WeatherVane 我假设作者将缓冲区初始化为零。 if 中还有一个 memset 为零
-
@john 好的,那么结束条件是
strlen(dataBuffer) == (BUFFER_SIZE - 1),而不是块大小。leftToSend未重置。 -
另外,我对块大小有点不清楚。您想一次发送 4 个字节吗?还是根据您的正确示例 5 个字节?还是 BUFFER_SIZE?