2013-03-26 38 views
8

Sto cercando di inviare un'immagine usando il socket ma devo anche inviare il nome del file. Sto usando un codice che mando il file ma quando invio il nome del file ricevo alcuni caratteri strani nel client.C++ invia file e testo tramite socket

Cliente:

#define PORT 20000 
#define LENGTH 512 

int main(int argc, char *argv[]){ 
int sockfd; 
int nsockfd; 
char revbuf[LENGTH]; 
struct sockaddr_in remote_addr; 

/* Get the Socket file descriptor */ 
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
{ 
    fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor! (errno = %d)\n",errno); 
    exit(1); 
} 

/* Fill the socket address struct */ 
remote_addr.sin_family = AF_INET; 
remote_addr.sin_port = htons(PORT); 
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr); 
bzero(&(remote_addr.sin_zero), 8); 

/* Try to connect the remote */ 
if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1) 
{ 
    fprintf(stderr, "ERROR: Failed to connect to the host! (errno = %d)\n",errno); 
    exit(1); 
} 
else 
    printf("[Client] Connected to server at port %d...ok!\n", PORT); 

/* Send File to Server */ 
//if(!fork()) 
//{ 
    char* fs_name = "house.jpg"; 
    char sdbuf[LENGTH]; 

      char buffer[256]; 
      int n; 
      fgets(buffer,255,stdin); 
      bzero(buffer,256); 
      n = write(sockfd,buffer, strlen(buffer)); 
      if(n<0) printf("Error: sending filename"); 

    printf("[Client] Sending %s to the Server... ", fs_name); 
    FILE *fs = fopen(fs_name, "r"); 
    if(fs == NULL) 
    { 
     printf("ERROR: File %s not found.\n", fs_name); 
     exit(1); 
    } 

    bzero(sdbuf, LENGTH); 
    int fs_block_sz; 
    while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs)) > 0) 
    { 
     if(send(sockfd, sdbuf, fs_block_sz, 0) < 0) 
     { 
      fprintf(stderr, "ERROR: Failed to send file %s. (errno = %d)\n", fs_name, errno); 
      break; 
     } 
     bzero(sdbuf, LENGTH); 
    } 
    printf("Ok File %s from Client was Sent!\n", fs_name); 
//} 


close (sockfd); 
printf("[Client] Connection lost.\n"); 
return (0); 
} 

parte di client che invia il testo:

char buffer[256]; 
int n; 
fgets(buffer,255,stdin); 
bzero(buffer,256); 
n = write(sockfd,buffer, strlen(buffer)); 
if(n<0) printf("Error: sending filename"); 

Server:

#define PORT 20000 
#define BACKLOG 5 
#define LENGTH 512 

int main() 
{ 
int sockfd; 
int nsockfd; 
int num; 
int sin_size; 
struct sockaddr_in addr_local; /* client addr */ 
struct sockaddr_in addr_remote; /* server addr */ 
char revbuf[LENGTH]; 

/* Get the Socket file descriptor */ 
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
{ 
    fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor. (errno = %d)\n", errno); 
    exit(1); 
} 
else 
    printf("[Server] Obtaining socket descriptor successfully.\n"); 

/* Fill the client socket address struct */ 
addr_local.sin_family = AF_INET; // Protocol Family 
addr_local.sin_port = htons(PORT); // Port number 
addr_local.sin_addr.s_addr = INADDR_ANY; // AutoFill local address 
bzero(&(addr_local.sin_zero), 8); // Flush the rest of struct 

/* Bind a special Port */ 
if(bind(sockfd, (struct sockaddr*)&addr_local, sizeof(struct sockaddr)) == -1) 
{ 
    fprintf(stderr, "ERROR: Failed to bind Port. (errno = %d)\n", errno); 
    exit(1); 
} 
else 
    printf("[Server] Binded tcp port %d in addr 127.0.0.1 sucessfully.\n",PORT); 

/* Listen remote connect/calling */ 
if(listen(sockfd,BACKLOG) == -1) 
{ 
    fprintf(stderr, "ERROR: Failed to listen Port. (errno = %d)\n", errno); 
    exit(1); 
} 
else 
    printf ("[Server] Listening the port %d successfully.\n", PORT); 

int success = 0; 
while(success == 0) 
{ 
    sin_size = sizeof(struct sockaddr_in); 

    /* Wait a connection, and obtain a new socket file despriptor for single connection */ 
    if ((nsockfd = accept(sockfd, (struct sockaddr *)&addr_remote, &sin_size)) == -1) 
    { 
     fprintf(stderr, "ERROR: Obtaining new Socket Despcritor. (errno = %d)\n", errno); 
     exit(1); 
    } 
    else 
     printf("[Server] Server has got connected from %s.\n", inet_ntoa(addr_remote.sin_addr)); 


      char buffer[256]; 
      bzero(buffer,256); 
      int n = 0; 
      n = read(nsockfd, buffer, 255); 
      if (n < 0) error("ERROR reading from socket"); 
      printf("msg: %s\n",buffer); 

    /*Receive File from Client */ 
    char* fr_name = "/house.jpg"; 
    FILE *fr = fopen(fr_name, "a"); 
    if(fr == NULL) 
     printf("File %s Cannot be opened file on server.\n", fr_name); 
    else 
    { 
     bzero(revbuf, LENGTH); 
     int fr_block_sz = 0; 
     while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) > 0) 
     { 
      int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr); 
      if(write_sz < fr_block_sz) 
      { 
       error("File write failed on server.\n"); 
      } 
      bzero(revbuf, LENGTH); 
      if (fr_block_sz == 0 || fr_block_sz != 512) 
      { 
       break; 
      } 
     } 
     if(fr_block_sz < 0) 
     { 
      if (errno == EAGAIN) 
      { 
       printf("recv() timed out.\n"); 
      } 
      else 
      { 
       fprintf(stderr, "recv() failed due to errno = %d\n", errno); 
       exit(1); 
      } 
     } 
     printf("Ok received from client!\n"); 
     fclose(fr); 
    } 
} 

}

parte di server che riceve il testo:

char buffer[256]; 
bzero(buffer,256); 
int n = 0; 
n = read(nsockfd, buffer, 255); 
if (n < 0) error("ERROR reading from socket"); 
printf("msg: %s\n",buffer); 

Ho bisogno di aiuto. Grazie ...

+1

A proposito, dai un'occhiata a "sendfile". –

+2

Usa RB, wb invece di r, w in fopen quando si ha a che fare con file binari – iamsleepy

risposta

3

In questo codice nel tuo client:

 char buffer[256]; 
     int n; 
     fgets(buffer,255,stdin); 
     bzero(buffer,256); 
     n = write(sockfd,buffer, strlen(buffer)); 

Sembra che si sta tentando di leggere il nome del file dal stdin e inviarlo sul sockfd. Ma. azzerare il buffer prima di inviarlo.

+0

Grazie mille, funziona ora! Grazie ! –