Question

I am sending data from client to server,But picture do not receive complete.

Client Code:

FILE *fr = fopen(tmppicsend, "rb");
char* buffer;
buffer = (char*) malloc(sizeof(char)*size);
fread(buffer, size, 1, fr);
send_len_pic = send( m_socket_pic, buffer, size, 0 );
recv( m_socket_pic, rec_end_check, 32, 0 );
fclose(fr);
free(buffer);

Server Code:

FILE *fw = fopen(fname, "wb");
char* buffer;
buffer = (char*) malloc(sizeof(char)*size);
int rec_len = recv( current_client, buffer, size, 0 );
buffer[size]='\0';
fwrite(buffer, size, 1, fw);
size -= size;
free(buffer);
fclose(fw);

Config Socket:

WSADATA wsaData_pic;
SOCKET m_socket_pic;
SOCKET m_backup_pic;
sockaddr_in con_pic;

 // Initialize Winsock.
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData_pic );
if ( iResult != NO_ERROR ){
    //printf("Error at WSAStartup()\n");
}
// Create a socket.
m_socket_pic = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

if ( m_socket_pic == INVALID_SOCKET ) {
    //printf( "Error at socket(): %ld\n", WSAGetLastError() );
    //WSACleanup();
}

m_backup_pic = m_socket_pic;

// Connect to a server.
con_pic.sin_family = AF_INET;
con_pic.sin_addr.s_addr = inet_addr( ip );
con_pic.sin_port = htons( 2200 );

if ( connect( m_backup_pic, (SOCKADDR*) &con_pic, sizeof(con_pic) ) == SOCKET_ERROR) {
    //printf( "Failed to connect.\n" );
    //WSACleanup();
}else
{   
    m_socket_pic=m_backup_pic;
}


}

When I'm comparing this pictures, i see error in sequence number packet(packets do not receive regularly ). Picture(Pic from Client and Server) were the same size. I want to send JPEG picture.

Please Help me, tanks.

Was it helpful?

Solution 7

I got many attempts to answer.

The best answer for this question is:

Sync client with server for send stream.

because the recv() function i slower than send() function, clients send amount of data that the server is able to receive.


Clients Code:

char* bufferCMP;
bufferCMP = (char*)malloc(sizeof(char) * size);
p_file = fopen(tmppicsend,"rb");
fread(bufferCMP, 1, size , p_file);
fclose(p_file);


int chunkcount = size / DEFAULT_BUFLEN;
int lastchunksize = size - (chunkcount * DEFAULT_BUFLEN);
int fileoffset=0;

//Sending Actual Chunks
while (chunkcount > 0)
{
    iResult = send( m_socket_pic, bufferCMP + (fileoffset * DEFAULT_BUFLEN) , DEFAULT_BUFLEN , 0 );
    fileoffset++;
    chunkcount--;

    if (iResult != DEFAULT_BUFLEN)
    {
        //printf("Sending Buffer size <> Default buffer length  ::: %d\n",WSAGetLastError());
    }
    else
    {
        //printf("Sending Buffer size = %d \n", iResult);
    }
}

//Sending last Chunk
iResult = send( m_socket_pic, bufferCMP + (fileoffset * DEFAULT_BUFLEN) , lastchunksize , 0 );

Server Code:

int FileCounter=0;
bool flg=true;
char * fileComplete;
char * filesizeBuffer;

FILE *temp;

int iResult;

int receiveBuffer = 0;
int desiredRecBuffer = size ;
//int desiredRecBuffer = DEFAULT_BUFLEN ; 
fileComplete = (char*) malloc (sizeof(char)* size );
while (desiredRecBuffer > 0)
{
    iResult = recv( current_client, fileComplete + receiveBuffer , desiredRecBuffer , 0 );
    //iResult = recv( ClientSocket, fileComplete + receiveBuffer , fileSize , 0 );

    if (iResult < 1)
    {
        //printf("Reveive Buffer Error  %d \n", WSAGetLastError());
    }
    else
    {
        receiveBuffer += iResult;
        desiredRecBuffer = size - receiveBuffer ;
        //printf("Reveived Data size :  %d \n", iResult);
    }
}

FILE *File = fopen(fname, "wb");
fwrite(fileComplete,1, size , File);
//flg = true;
free(fileComplete);
fclose(File);

OTHER TIPS

You are making the usual mistakes. You can't assume that recv() fills the buffer. You have to loop until you have all the data you need, and you have to make use of the count value returned by recv().

How do you know the size of the data to receive on the server-side? You should establish some sort of protocol (defined by yourself) between the server and the client. The easiest way is in the first place to send uint64_t (8 bytes) which will hold the picture size, and after that send the data itself. And then after the server reads these first 8 bytes - it will know how much data to expect. Then you just repeat recv() calls until you get all of the data sent by the client. It is a good idea to use select() on the server side to wait until the next data portion is available. Btw, if the picture you are trying to send is big enough (and in the most cases it is true), it is sent over the tcp or udp connection part by part, not by a one big piece. And it is unpredictable (the hardware decides it) how big the pieces or how much of them would be sent. So you absolutely should be prepared to repeatedly call recv() to receive all the data the client sends to the server.

I think the reason is the size of data you are sending, because when you send large packet over network the underlying layers will divide this large packet into small packets and then send those packets over network.

so when you receive these packets the sequence of these packets might change, thats why you are receiving the same size of data, but the image is not correct.

i will give you a quick solution you can try,

Divide your file into small arrays, lets say each array is 1024 byte, first send the count of these arrays, after that start sending the first array (1024 byte), and then wait for acknowledgement from the other side, repeat until you send all data.

you can do it without acknowledgement, but leave sometime between each send.

Have you tried to convert the image buffer to base64, send it to the receiver-part of your code and then un-base and malloc it?

The above way is how our screenshot program work (for remote administration) and it works like a charm..

Client code

    /*
     * Send size of the file first.
     */

    n = sizeof(filesize);
    r = send(m_socket_pic, &filesize, n);
    if (r != n) {
        printf("error sending %d bytes\n", n);
    }       

    /*
     * Now send the file.
     */

    n = filesize;
    while (n > 0) {
        r = send(m_socket_pic, buffer, n, 0);
        buffer += r;
        n -= r;    
    }       

Server code

    /*
     * Recv size of the file first.
     */

    n = sizeof(filesize);
    r = recv(current_client, &filefsize, n);
    if (r != n) {
        printf("error receiving %d bytes\n", n);
    }

    /*
     * Now recv the file.
     */

    n = filesize;
    while (n > 0) {
        r = recv(current_client, buffer, n, 0);
        buffer += r;
        n -= r;
    }

Thanks to all,

The Problem is , Sending large file through sockets.

I have test many ways, But did not answer problem.

It is known,I should use loop for send split data.

The best split size is 512 or 1500, And great problem is in recv() function, This function is very slower than send() function.When I use Sleep(1000) in loop block, Reduced the number of damaged photos.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top