Vlad
Vlad

Reputation: 35

sending a .txt file via tcp/ip protocol in c++

I'm trying to make a program which sends to the server a .txt file, modifies it's content and then sends the modified content back to the client in C++. I have managed to make the tcp/ip communication to work fine for simple string text messages, but when I try to send the content of a .txt file, it fails to do so.

Here's a snippet of my code: (

Client:

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();
}

Server:

// 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();

}

Using debug mode, I noticed that in server side

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

it can't get to the second row of my text file.

P.S. : I'm new to tcp/ip on c++, having basic experience on Java, Any help is great, thanks.

Upvotes: 0

Views: 2523

Answers (1)

Robert Andrzejuk
Robert Andrzejuk

Reputation: 5222

Generally some kind of communication protocol needs to be defined to send and receive the data cleanly. Especially if You sending and recieving multiple messages.

Here the data is been sent and received both from the client and server without any consideration in which state is the other application.

I guess that maybe the client has closed down the connection and the server cannot send the reply so it doesn't continue to receive the next messages.

I have to guess because the whole code is not provided to reproduce.

You should do some debugging - checking in which state is ether application and what is going on inside the code. Use two IDE's - one for the server, one for the client.

Below is a simple client which sends it's information to the server, and the server just receives it.

If a more complicated scenario is needed then You have to think about how the client and server will agree between each other, how to know what to do next.


client and server code is according to MSDN: Running the Winsock Client and Server Code Sample

In the // Send an initial buffer the function should send the data and check how much data has already been sent.

Something like this:

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 );

On the recieving side the code also has to recieve in a loop like in the example:

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

} while ( iResult > 0 );

I used a 2MB test file and the send command worked by sending in one shot all the data.

On the recieving end, the data was recieved in 512byte batches, which means there where many iterations of the loop.

Upvotes: 2

Related Questions