代码之家  ›  专栏  ›  技术社区  ›  Vlad

正在发送。c中通过tcp/ip协议的txt文件++

  •  0
  • Vlad  · 技术社区  · 7 年前

    我正在尝试制作一个程序,将其发送到服务器a。txt文件,修改其内容,然后用C++将修改后的内容发送回客户端。我已经设法使tcp/ip通信对于简单的字符串文本消息很好地工作,但是当我尝试发送的内容时。txt文件,则无法执行此操作。

    下面是我的代码片段:(

    客户:

    fstream file;
    string fileName = "Test.txt";
    string textToSend;
    int sendResult;
    
    file.open(fileName);
    
    while (!file.eof())
    {
        getline(file, textToSend);
        sendResult = send(sock, textToSend.c_str(), textToSend.size() + 1, 0);
    }
    string end_msg = "end";
    sendResult = send(sock, end_msg.c_str(), end_msg.size() + 1 , 0);
    
    file.close();
    
    if (sendResult != SOCKET_ERROR)
    {
        ZeroMemory(buf, 4096);
    
        int bytesReceived = recv(sock, buf, 4096, 0);
    
        if (bytesReceived > 0)
        {
            cout << "Server> " << string(buf, 0, bytesReceived) << endl;
        }
        else
        {
            cout << "Error on client - bytesReceived" << endl;
        }
    }
    
    // Gracefully close down everything
    closesocket(sock);
    WSACleanup();
    }
    

    服务器:

    // While loop: accept and echo message back to client
    char buf[4096];
    
    while (true)
    {
        ZeroMemory(buf, 4096);
    
        // Wait for client to send data
        int bytesReceived = recv(clientSocket, buf, 4096, 0);
    
        if (bytesReceived == SOCKET_ERROR)
        {
            cerr << "Error in recv(). Quitting!" << endl;
            break;
        }
        else
        {
            if (bytesReceived == 0)
            {
                cout << "Client disconnected!" << endl;
                break;
            }
        }
    
        buf[bytesReceived] = '\0';
        while (buf != "end")
        {
            cout << buf << endl;
            bytesReceived = recv(clientSocket, buf, 4096, 0); //Here seems to be the problem in debug mode
            buf[bytesReceived] = '\0';
        }
    
        cout << string(buf, 0, bytesReceived) << endl;
    
        // Echo message back to client
        send(clientSocket, buf, bytesReceived + 1, 0);
    }
    
    // Close socket
    closesocket(clientSocket);
    
    // Shutdown Winsocket
    WSACleanup();
    

    }

    在使用调试模式时,我注意到在服务器端

    bytesReceived = recv(clientSocket, buf, 4096, 0);
    

    它无法到达文本文件的第二行。

    P、 S:我不熟悉c++上的tcp/ip,有Java的基本经验,任何帮助都很好,谢谢。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Robert Andrzejuk    7 年前

    通常是某种 通信协议 需要定义以干净地发送和接收数据。尤其是当您发送和接收多条消息时。

    在这里,数据从客户端和服务器发送和接收,而不考虑状态是另一个应用程序。

    我猜可能是客户端关闭了连接,服务器无法发送回复,因此无法继续接收下一条消息。

    我不得不猜测,因为没有提供完整的代码来复制。

    您应该进行一些调试-检查以太应用程序处于哪个状态,以及代码内部发生了什么。使用两个IDE—一个用于服务器,一个用于客户端。

    下面是一个简单的客户端,它将信息发送到服务器,而服务器只接收信息。

    如果需要一个更复杂的场景,那么您必须考虑客户机和服务器之间如何达成一致,以及如何知道接下来要做什么。


    客户端和服务器代码符合 MSDN: Running the Winsock Client and Server Code Sample

    // Send an initial buffer 函数应发送数据并检查已发送的数据量。

    类似这样:

    std::ifstream file( "Test.txt" );
    std::string   content( ( std::istreambuf_iterator< char >( file ) ),
                         ( std::istreambuf_iterator< char >() ) );
    
    
    // Send an initial buffer
    int bytes_to_send = content.length();
    int bytes_sent    = 0;
    do
    {
        iResult = send( ConnectSocket, content.data() + bytes_sent, bytes_to_send, 0 );
        if ( iResult != SOCKET_ERROR )
        {
            bytes_to_send -= iResult;
            bytes_sent += iResult;
        }
    } while ( iResult != SOCKET_ERROR && bytes_to_send > 0 );
    

    在接收端,代码还必须在循环中接收,如示例所示:

    // Receive until the peer shuts down the connection
    do
    {
        iResult = recv( ClientSocket, recvbuf, recvbuflen, 0 );
        if ( iResult > 0 )
        {
             //...
    
    } while ( iResult > 0 );
    

    我使用了一个2MB的测试文件 send 命令通过一次发送所有数据来工作。

    在接收端,数据以512byte的批次接收,这意味着有许多循环迭代。