Envoyer Image par socket (send func) en c ++, mais ne pas recevoir complètement (Windows)!

J’envoie des données du client au serveur, mais l’image n’est pas complète.

Code client:

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

Code serveur:

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

Prise de configuration:

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

Lorsque je compare ces images, je vois une erreur dans le paquet de numéro de séquence (les paquets ne sont pas reçus régulièrement). L’image (Pic du client et du serveur) avait la même taille. Je veux envoyer une image JPEG.

S’il vous plaît, aidez-moi, les chars.

Vous faites les erreurs habituelles. Vous ne pouvez pas supposer que recv () remplit le tampon. Vous devez boucler jusqu’à ce que vous ayez toutes les données dont vous avez besoin, et vous devez utiliser la valeur de comptage renvoyée par recv ().

Comment connaître la taille des données à recevoir côté serveur? Vous devez établir une sorte de protocole (défini par vous-même) entre le serveur et le client. Le moyen le plus simple consiste en premier lieu à envoyer uint64_t (8 octets) qui contiendra la taille de l’image, puis à envoyer les données elles-mêmes. Et après que le serveur ait lu ces 8 premiers octets, il saura à quelle quantité de données il faut s’attendre. Ensuite, il vous suffit de répéter les appels recv () jusqu’à ce que vous obteniez toutes les données envoyées par le client. C’est une bonne idée d’utiliser select() côté serveur pour attendre que la prochaine partie de données soit disponible. Btw, si l’image que vous essayez d’envoyer est assez grande (et dans la plupart des cas elle est vraie), elle est envoyée par partie de connexion tcp ou udp, pas par un gros morceau. Et il est imprévisible (le matériel le décide) quelle est la taille des pièces ou combien d’entre elles seraient envoyées. Donc, vous devez absolument être prêt à appeler plusieurs fois recv () pour recevoir toutes les données que le client envoie au serveur.

Je pense que la raison en est la taille des données que vous envoyez, car lorsque vous envoyez des paquets volumineux sur le réseau, les couches sous-jacentes divisent ce grand paquet en petits paquets, puis envoient ces paquets sur le réseau.

Ainsi, lorsque vous recevez ces paquets, la séquence de ces paquets peut changer, c’est pourquoi vous recevez la même taille de données, mais l’image n’est pas correcte.

Je vais vous donner une solution rapide que vous pouvez essayer,

Divisez votre fichier en petits tableaux, disons que chaque tableau est de 1024 octets, commencez par envoyer le nombre de ces tableaux, puis commencez à envoyer le premier tableau (1024 octets), puis attendez de l’autre côté pour répéter Les données.

vous pouvez le faire sans accusé de réception, mais laissez-le entre chaque envoi.

Avez-vous essayé de convertir le tampon d’image en base64, l’envoyer à la partie receveur de votre code, puis le désinstaller et le joindre?

La méthode ci-dessus est la façon dont fonctionne notre programme de capture d’écran (pour l’administration à distance) et cela fonctionne comme un charme ..

Code client

  /* * 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; } 

Code serveur

  /* * 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; } 

Merci à tous,

Le problème est, Envoi de gros fichiers via des sockets.

J’ai testé de nombreuses façons, mais n’a pas répondu au problème.

Il est connu que je devrais utiliser une boucle pour envoyer des données fractionnées.

La meilleure taille de fractionnement est 512 ou 1500, et le grand problème est dans la fonction recv() , cette fonction est très lente que la fonction send() . Lorsque j’utilise Sleep(1000) dans le bloc de boucle, réduit le nombre de photos endommagées.

J’ai eu beaucoup de tentatives pour répondre.

La meilleure réponse à cette question est:

Synchroniser le client avec le serveur pour le stream d’envoi.

Comme la fonction recv () est plus lente que la fonction send (), les clients envoient une quantité de données que le serveur peut recevoir.


Code client:

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

Code serveur:

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