我编写了一个简单的FTP应用程序,可以在客户端和服务器之间来回发送文件,并且工作正常。最近我编写了一个与客户端和服务器一起使用的套接字库,其中一些功能已经改变,而且我无法解决如何让它工作的问题。目前我正在将库集成到我的服务器上。
问题是我的规范的一部分是用库隐藏套接字句柄,所以我在库函数中包装'recv'和'send',它们通过引用传递一个char指针。在我实现这个之前,我将char []直接传递给recv函数,这些函数很适合我的目的。现在我正在使用char *,看起来我需要知道传入消息的确切长度,因为我的char *出现了发送数据以及垃圾字符。
以下是我的服务器代码的一部分:
while (true)
{
command = (char*)malloc(sizeof(char)*32);
int bytesRecv = socketObject.receiveData('c', &command, 32);
if(_stricmp(command,"mput") == 0)
{
while( true ) {
SizeCheck = 0;
FileSize = 0;
fileName = (char*)malloc(sizeof(char)*1024);
bytesRecv = socketObject.receiveData('c', &fileName, 1024);
if(_stricmp(fileName,"goodbye") == 0)
{
break;
}
while( true )
{
char GotFileSize[1024];
GotFileSize = (char*)malloc(sizeof(char)*1024);
socketObject.receiveData('c', &sentSize, 1024);
FileSize = atoi(GotFileSize);
if (FileSize > 0)
{
break;
}
}
mfcc = (char*)malloc(sizeof(char)*FileSize);
FILE *fp;
if( (fp = fopen(fileArray, "wb")) == NULL)
{
std::cout << "fopen has caused an error" << endl;
}
while(SizeCheck < FileSize){
int Received = socketObject.receiveData('f', &mfcc, FileSize);
if(Received != SOCKET_ERROR)
{
std::cout << "Before fwrite" << std::endl;
int written = fwrite(mfcc, 1, FileSize, fp);
SizeCheck += Received;
fflush(fp);
}
}//while transfer
}//while true
}//end mput if
这是我的接收功能:
int Socket::receiveData( char socketType, char** data, int size)
{
if(socketType != 'f' && socketType != 'c')
{
return -1;
}
if(socketType == 'f')
{
int bytes = recv( fAccepted, *data, size, 0);
return bytes;
}
else if(socketType == 'c')
{
int bytes = recv( cAccepted, *data, size, 0);
if (bytes == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
}
return bytes;
}
return -1;
}
我已经完成了对recv的一些阅读,告诉我我应该以某种方式用文件名发送文件名的大小,或者在循环中编译一个完整的字符串。我不确定这些方法是否适合我正在尝试做的事情,或者是否有更简单的方法。
答案 0 :(得分:2)
receiveData
函数非常好:它将接收到的字节写入缓冲区,并返回接收到的字节数。
缓冲区中的所有其他字节可以而且应该被忽略。
在您当前的代码中,每次接收数据时,您都会将整个缓冲区写入文件,即使receiveData
准确地告诉您应该写入多少数据。
即,你不应该做
int written = fwrite(mfcc, 1, FileSize, fp);
但是
int written = fwrite(mfcc, 1, Received, fp);
您应该考虑使用更合理的缓冲区大小,例如1500字节(网络数据包的通常MTU),或1MB(应该适合RAM而没有问题),而不是完整的文件大小。
顺便说一句,没有必要将data
作为双指针传递,或者,就像你所说的那样,作为对指针的引用。只需将其作为普通指针传递即可。但这与你的“垃圾数据”问题无关。