Sto scrivendo un piccolo programma C per poter trasferire un file immagine tra due computer (da server a client entrambi in esecuzione Linux) usando socket TCP/IP ma lì sembra essere un errore in quanto la mia immagine appare danneggiata negli altri lati.Invio immagine (JPEG) tramite Socket in C Linux
Il codice per il mio server è in quanto tale:
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<iostream>
#include<fstream>
#include<errno.h>
using namespace std;
int send_image(int socket){
FILE *picture;
int size, read_size;
char send_buffer[10240], verify;
picture = fopen("2.jpg", "r");
printf("Getting Picture Size\n");
if(picture == NULL) {
printf("Error Opening Image File");
}
fseek(picture, 0, SEEK_END);
size = ftell(picture);
fseek(picture, 0, SEEK_SET);
//Send Picture Size
printf("Sending Picture Size\n");
write(socket, (void *)&size, sizeof(int));
if(read_size = read(socket, &verify , sizeof(char)) < 0) {
puts("\nError Receiving Verification");
}
if(verify == '1'){
printf("5\n");
//Send Picture as Byte Array
printf("Sending Picture as Byte Array\n");
while(!feof(picture)) {
//Read from the file into our send buffer
read_size = fread(send_buffer, 1, sizeof(send_buffer)-1, picture);
//Send data through our socket
write(socket, send_buffer, read_size);
//Wait for the verify signal to be received
while(read(socket, &verify , sizeof(char)) < 0);
if(verify != '1') {
printf("Error Receiving the Handshake signal\n %s",&verify);
}
verify = '';
//Zero out our send buffer
bzero(send_buffer, sizeof(send_buffer));
}
}
}
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c, read_size,buffer = 0;
struct sockaddr_in server , client;
char *readin;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8889);
//Bind
if(bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
if((new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c))){
puts("Connection accepted");
}
fflush(stdout);
if (new_socket<0)
{
perror("Accept Failed");
return 1;
}
send_image(new_socket);
close(socket_desc);
fflush(stdout);
return 0;
}
Il codice lato client che sta ricevendo i dati sono in quanto tale:
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<sys/ioctl.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<iostream>
#include<errno.h>
using namespace std;
//This function is to be used once we have confirmed that an image is to be sent
//It should read and output an image file
int receive_image(int socket){
int buffersize = 0, recv_size = 0,size = 0, read_size, write_size;
char imagearray[10241],verify = '1';
FILE *image;
//Find the size of the image
read(socket, &size, sizeof(int));
//Send our verification signal
write(socket, &verify, sizeof(char));
//Make sure that the size is bigger than 0
if(size <= 0){
printf("Error has occurred. Size less than or equal to 0\n");
return -1;
}
image = fopen("2.jpg", "w");
if(image == NULL) {
printf("Error has occurred. Image file could not be opened\n");
return -1;
}
//Loop while we have not received the entire file yet
while(recv_size < size) {
ioctl(socket, FIONREAD, &buffersize);
//We check to see if there is data to be read from the socket
if(buffersize > 0) {
if(read_size = read(socket,imagearray, buffersize) < 0){
printf("%s", strerror(errno));
}
//Write the currently read data into our image file
write_size = fwrite(imagearray,1,(buffersize), image);
if(write_size != buffersize) {
printf("write and buffersizes wrong");
}
if(read_size !=write_size) {
printf("error in read write");
}
//Increment the total number of bytes read
recv_size += read_size;
//Send our handshake verification info
write(socket, &verify, sizeof(char));
}
}
fclose(image);
printf("Image successfully Received!\n");
return 1;
}
int main(int argc , char *argv[])
{
int socket_desc;
struct sockaddr_in server;
char *parray;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1) {
printf("Could not create socket");
}
memset(&server,0,sizeof(server));
server.sin_addr.s_addr = inet_addr("10.42.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8889);
//Connect to remote server
if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0) {
cout<<strerror(errno);
close(socket_desc);
puts("Connect Error");
return 1;
}
puts("Connected\n");
receive_image(socket_desc);
close(socket_desc);
return 0;
}
Qualcuno può darmi una mano con questo? Non riesco a vedere per capire questo errore per la vita di me.
EDIT: ho cambiato le fwrites e freads indietro nella scrittura regolare e leggere e invia comunque un immagine corrotta
Non hai bisogno di '' ioctl' e FIONREAD'; lasciatelo bloccare se non ci sono ancora dati. Non è che tu stia facendo qualcos'altro nel frattempo. – icktoofay
Hai confermato che ogni singolo read_size corrisponde a ogni singolo write_size? –
Possibile duplicato di [Invia e ricevi un file in programmazione socket in Linux con C/C++ (GCC/G ++)] (http://stackoverflow.com/questions/2014033/send-and-receive-a-file-in- programmazione socket in-linux-con-cc-gcc-g) –