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

时间:2018-02-09 15:50:30

标签: c++ sockets tcp

我试图创建一个向服务器发送.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 个答案:

答案 0 :(得分:1)

通常需要定义某种通信协议来干净地发送和接收数据。特别是如果您发送和接收多条消息。

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

我想也许客户端关闭了连接,服务器无法发送回复,因此它不会继续接收下一条消息。

我必须猜测,因为没有提供整个代码来重现。

你应该做一些调试 - 检查哪个状态是以太应用程序以及代码内部发生了什么。使用两个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命令通过一次性发送所有数据来工作。

在接收端,数据以512字节的批次收到,这意味着循环的迭代很多。