简体   繁体   English

接收到一个sendFile()函数后recv没有停止

[英]recv's not stoping after receiving a transmitFile() function

I'm writing a small Server/Client Filetransfer using Winsocket for class and it basicly works except that i can't receiv any more messages on the socket after I receiv the file and write it to my HDD. 我正在使用Winsocket编写用于类的小型服务器/客户端文件传输,它基本上可以正常工作,除了在接收文件并将其写入我的HDD之后无法再在套接字上接收任何消息。

The transmit code loosk like this: 传输代码如下所示:

    long size = GetFileSize(hFile, NULL);
TransmitFile(_socket, hFile, size, 0, NULL, NULL, TF_DISCONNECT);
ok = ::recv(_socket, cantwortfilename, 100, 0); // getting a confirmation (1)
cantwortfilename[ok] = '\0';
cout << cantwortfilename << endl;
char test[] = "ok!";
::send(_socket, test, strlen(test), 0); // to test if server receives again (2)

I tried it with 0 instead of size with same results. 我用0而不是大小尝试了相同的结果。

now to the receiving on the server side: 现在到服务器端的接收端:

    HANDLE hFile = CreateFile(filepathlong, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

while (1)
{
    ReadFile((HANDLE)_socket, &buffer, MAX_PATH, &dwbr, &AsyncInfo);
    GetOverlappedResult((HANDLE)_socket, &AsyncInfo, &dwbr, TRUE);
    if (dwbr == 0) break;
    WriteFile(hFile, buffer, dwbr, &dwbr, NULL);
}
char test[] = "alles ok!";
::send(_socket, test, strlen(test), 0); // sending the confirmation (1)

CloseHandle(hFile);

 i = ::recv(_socket, test, 10, 0); // receiving the test (2)
test[i] = '\0';
cout << "empfangen:" << test << endl;

The transfer of the file works fine as far as i can tell (tried rar jpg .h) and the 据我所知(尝试过rar jpg .h),文件的传输工作正常

::send(_socket, test, strlen(test), 0); // sending the confirmation (1)

gets out fine too. 出去也很好。

but the receiving after that gives me nothing? 但是那之后的收受给我什么呢? or something empty? 还是空的? I would guess something empty since the recv doesn't block the program either. 我想猜是空的,因为recv也不会阻止程序。 But "i" will be 0 when i give it out. 但是当我给出它时,“ i”将为0。

to check if i made some kind of error with the stuff in the while(1) loop i tried another way to receiv the file. 检查while(1)循环中的东西是否出错了,我尝试了另一种方式来接收文件。

the 2nd try: 第二次尝试:

    int r;
ofstream file(filepath, std::ios::out | std::ios::binary | std::ios::trunc);
char *memblock;
int size = 7766; // was the size of the file i was testing with
memblock = new char[size];
memset(memblock, 0, size);
if (file.is_open()){
    //while memory blocks are still being received
    while ((r = recv(_socket, memblock, 256, 0)) != 0)
    {
        //if there's a socket error, abort
        if (r == SOCKET_ERROR)
        {
            cout << "error" << endl;
        }
        //write client's file blocks to file on server
        file.write(memblock, r);
    }
    delete[] memblock;
    //finished sending memory blocks; file is completely transferred.
    file.close();
}

after that, again a send a recv with the same result. 之后,再次发送具有相同结果的recv。 The file worked but receiving again got me something empty. 该文件有效,但是再次收到却让我有些空白。

So can anyone tell me why and how can fix this? 那么谁能告诉我原因以及如何解决呢? If possible with the least change possible? 如果可能的话,进行最少的更改?

Thanks, Martin 谢谢马丁

EDIT: Code that is working for me now: 编辑:现在为我工作的代码:

    char csize[256];
rc = recv(_socket, csize, 256, 0);
csize[rc] = '\0';
int size = atoi(csize);
int bytes_read = 0, len = 0;

int r;
ofstream file(filepath, std::ios::out | std::ios::binary | std::ios::trunc);
char *memblock;
memblock = new char[size];
memset(memblock, 0, size);

if (file.is_open()){
    while (bytes_read < size){
        len = recv(_socket, memblock + bytes_read, size - bytes_read, 0);
        bytes_read += len;
    }
    file.write(memblock, size);
    delete[] memblock;
    file.close();
}

Your transmitter is calling TransmitFile() with the TF_DSCONNECT flag. 您的发送器正在调用带有TF_DSCONNECT标志的TransmitFile() That will close the socket after the file has finished being sent. 发送完文件后,将关闭套接字。 The transmitter can't send any more data once TransmitFile() has exited (I am not sure if TransmitFile() only does a half-duplex close to close just the send direction but leaves the receive direction open, or if it does a full-duplex close on both send and receive directions - I would err on the side of caution and assume the latter). 一旦TransmitFile()退出,发送器将无法再发送任何数据(我不确定TransmitFile()仅对半双工进行关闭以仅关闭发送方向,而使接收方向保持打开状态,或者是否执行了全双工操作) -duplex在发送和接收方向上均关闭-我会谨慎行事并假定后者)。

Based on what you have shown, you need to use shutdown() and closesocket() instead of TF_DISCONNECT so you have more control over when and how the disconnect actually occurs. 根据显示的内容,您需要使用shutdown()closesocket()而不是TF_DISCONNECT以便可以更好地控制断开连接的时间和方式。

Also, TransmitFile() does not send the file size, only the file data, so your receiver has no way of knowing when the file data has actually finished being received, unless it waits for a timeout (which is not a reliable solution). 另外, TransmitFile()不会发送文件大小,而只会发送文件数据,因此,除非等待超时(这不是一个可靠的解决方案),否则接收方无法知道何时真正完成接收文件数据。 You need to change your transmitter to send the file size before sending the file data, then change your receiver to read the file size first and then loop until it has received the specified number of bytes. 您需要先更改发送器以发送文件大小,然后再发送文件数据,然后更改接收器以首先读取文件大小,然后循环播放,直到接收到指定的字节数为止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM