Linux服务器,发送文件到Windows客户端(套接字)

当我发送文件到客户端它被损坏,并以字节的大小更高。

我有一个在Windows上运行的服务器的版本,完美的工作,但我没有在Linux上有相同的结果。

磁盘上的文件大小可能是将大小(以字节为单位)发送到在另一个平台上运行的客户端的错误?

客户端完美的工作,正如我所说我有一个在Windows上运行此服务器的版本,唯一的区别是fread: Size = fread(mfcc, 1, min(sizeof(mfcc), FileSize), fp);

fread函数是否正确使用?

专家可以分析和帮助find错误?

 int Socket_Setup::FILE_UPLOAD(int iD, std::string DIR_UPLOAD) { char Block[1024]; long FileSize; fp = fopen(DIR_UPLOAD.c_str(), "rb"); if (!fp) { errno_message.append((char*)strerror(errno)); FUNCTION_LOG(errno_message); return 1; } fseek(fp, 0, SEEK_END); FileSize = ftell(fp); rewind(fp); long Size_Send = htonl(FileSize); Total = FileSize; // Sending the file size to the Windows Client iResult = send(client[iD].socket, (const char*)&Size_Send, sizeof(long), 0); if (iResult <= 0) { errno_message.append((char*)strerror(errno)); FUNCTION_LOG(errno_message); return 1; } while (FileSize > 0) { BytesRead = fread(Block, 1, sizeof(Block), fp); if (BytesRead <= 0) { errno_message.append((char*)strerror(errno)); FUNCTION_LOG(errno_message); fclose(fp); return 1; } if (send(client[iD].socket, Block, BytesRead, 0) != BytesRead) { errno_message.append((char*)strerror(errno)); FUNCTION_LOG(errno_message); fclose(fp); return 1; } FileSize -= BytesRead; } fclose(fp); return 0; } 

我认为你的问题在这里:

 iResult = send(client[iD].socket, (const char*)&Size_Send, Size_Send, 0); 

你用这个调用发送Size_Send字节(大部分是Size_Send变量结束之后的杂项内存),而不是你想要的,也就是发送sizeof(long)字节。 用sizeof(long)替换上面第二行的Size_Sent的第二个实例,你会得到一个更好的结果。

假设使用POSIX套接字(IEEE标准1003.1,2013版) 。

分析

我们来考虑下面的几段代码:

  1. 发送文件大小。

     // Sending the file size to the Windows Client iResult = send(client[iD].socket, (const char*)&Size_Send, sizeof(long), 0); if (iResult <= 0) { errno_message.append((char*)strerror(errno)); FUNCTION_LOG(errno_message); return 1; } 
  2. 发送“块”。

     if (send(client[iD].socket, Block, BytesRead, 0) != BytesRead) { errno_message.append((char*)strerror(errno)); FUNCTION_LOG(errno_message); fclose(fp); return 1; } 

send()函数并不保证所有的数据都会被“立即”发送(即使用单个函数调用):

返回值

成功完成后, send()应返回发送的字节数。 否则,返回-1,并errno来指示错误。

– 发送 – 在套接字上发送消息,Open Group Base Specification Issue 7,IEEE Std 1003.1,2013 Edition 。

因此, if (send(client[iD].socket, Block, BytesRead, 0) != BytesRead)检查似乎不正确。

必须使用send()函数的返回值来实现循环,以发送fread()函数调用之前读取的所有字节。 请参阅SendAllBytes()函数的实现。 它应该用于纠正这两个代码段(请参阅“分析”部分)。

下面的代码应该被视为一个例子:

 #include <stdio.h> #include <sys/socket.h> ... if (SendAllBytes(socket, &file_size, sizeof(file_size)) != 0) { // Error. return; } ... char buffer[1024]; while (feof(file_stream) == 0) { const size_t bytes_read = fread(buffer, sizeof(*buffer), sizeof(buffer) / sizeof(*buffer), file_stream); // Upon successful completion, fread() shall return the number of elements // successfully read which is less than nitems only if a read error or end-of-file is encountered. // If size or nitems is 0, fread() shall return 0 and the contents of the array and the state of the stream remain unchanged. // Otherwise, if a read error occurs, the error indicator for the stream shall be set, and errno shall be set to indicate the error. // (Source: http://pubs.opengroup.org/onlinepubs/9699919799/functions/fread.html). if (bytes_read < sizeof(buffer) / sizeof(*buffer) && ferror(file_stream) != 0) { // Error. return; } if (SendAllBytes(socket, buffer, bytes_read) != 0) { // Error. return; } } int SendAllBytes(int socket, const char *buffer, size_t bytes_to_send) { size_t total_bytes_sent = 0; while (bytes_to_send > 0) { const ssize_t bytes_sent = send(socket, &buffer[total_bytes_sent], bytes_to_send, 0); // Upon successful completion, send() shall return the number of bytes sent. // Otherwise, -1 shall be returned and errno set to indicate the error. // (Source: http://pubs.opengroup.org/onlinepubs/9699919799/). if (bytes_sent == -1) { // Error. return -1; } total_bytes_sent += bytes_sent; bytes_to_send -= bytes_sent; } return 0; } 

可移植性说明

考虑使用固定宽度的整数类型来增强可移植性。 在所描述的情况下,文件大小不是由固定宽度整数类型表示的。