为recv函数获取缓冲区len

时间:2014-04-02 23:36:05

标签: c++ sockets pointers char recv

我编写了一个简单的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的一些阅读,告诉我我应该以某种方式用文件名发送文件名的大小,或者在循环中编译一个完整的字符串。我不确定这些方法是否适合我正在尝试做的事情,或者是否有更简单的方法。

1 个答案:

答案 0 :(得分:2)

receiveData函数非常好:它将接收到的字节写入缓冲区,并返回接收到的字节数。

缓冲区中的所有其他字节可以而且应该被忽略。 在您当前的代码中,每次接收数据时,您都会将整个缓冲区写入文件,即使receiveData准确地告诉您应该写入多少数据。

即,你不应该做

int written = fwrite(mfcc, 1, FileSize, fp);

但是

int written = fwrite(mfcc, 1, Received, fp);

您应该考虑使用更合理的缓冲区大小,例如1500字节(网络数据包的通常MTU),或1MB(应该适合RAM而没有问题),而不是完整的文件大小。

顺便说一句,没有必要将data作为双指针传递,或者,就像你所说的那样,作为对指针的引用。只需将其作为普通指针传递即可。但这与你的“垃圾数据”问题无关。