2012-06-27 14 views
5

Innanzitutto, grazie a tutti per aver letto e aiutato, sono molto grato.
Secondo mi dispiace ma sono ancora nuovo in questo sito e l'inglese non è la mia lingua madre, quindi potrei fare alcuni errori di formattazione e di linguaggio. Mi scuso in anticipo.
Inoltre, la mia conoscenza di C non è buona, ma sono disposta a imparare e migliorare.
Ora, per la materia attuale:Invio e ricezione di un file (server/client) in C tramite socket su Unix

Quello che devo fare è creare un client e un server e fare in modo che il server ascolti le connessioni in entrata.
Quindi il client invia un file di testo piuttosto grande (so che sarà solo un file) al server.
Il server eseguirà quindi alcune operazioni sul file (eseguirà uno script sul file inviato che produce un altro file in uscita chiamato "output.txt"). Il server dovrà quindi inviare il file output.txt al client.

Ora, ho avuto modo di creare un client e un server (ho letto la guida beej e alcune altre cose su questo sito), anche se probabilmente ho fatto degli errori. Ho bisogno di aiuto con il server che recupera il file, poi chiama lo script e invia l'altro file al client. Per ora quello che ho fatto è il server e il client ... non so davvero come andare avanti.
In una nota a margine, ho creato questi file utilizzando ciò che ho trovato su questo sito e su Internet, spero che non siano troppo disordinati, dato che non sono così bravo in un programmatore.

Questo è client.c

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <pthread.h> 


#define SOCKET_PORT "50000" 
#define SOCKET_ADR "localhost" 
#define filename "/home/aryan/Desktop/input.txt" 


void error(const char *msg) 
{ 
    perror(msg); 
    exit(0); 
} 


int main() 
{ 
/* Making the client */ 
int sockfd, portno, n; 
struct sockaddr_in serv_addr; 
struct hostent *server; 

char buffer[256]; 

portno = atoi(SOCKET_PORT); 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
    error("ERROR opening socket"); 

server = gethostbyname(SOCKET_ADR); 

if (server == NULL) 
{ 
    fprintf(stderr,"ERROR, no such host\n"); 
    exit(0); 
} 

bzero((char *) &serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
bcopy((char *)server->h_addr, 
    (char *)&serv_addr.sin_addr.s_addr, 
    server->h_length); 
serv_addr.sin_port = htons(portno); 
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
    error("ERROR connecting"); 

/* Time to send the file */ 
FILE *pf; 
unsigned long fsize; 

pf = fopen(filename, "rb"); 
if (pf == NULL) 
{ 
    printf("File not found!\n"); 
    return 1; 
} 
else 
{ 
    printf("Found file %s\n", filename); 

    fseek(pf, 0, SEEK_END); 
    fsize = ftell(pf); 
    rewind(pf); 

    printf("File contains %ld bytes!\n", fsize); 
    printf("Sending the file now"); 
} 

while (1) 
{ 
    // Read data into buffer. We may not have enough to fill up buffer, so we 
    // store how many bytes were actually read in bytes_read. 
    int bytes_read = fread(buffer, sizeof(char),sizeof(buffer), pf); 
    if (bytes_read == 0) // We're done reading from the file 
     break; 

    if (bytes_read < 0) 
    { 
     error("ERROR reading from file"); 
    } 

    // You need a loop for the write, because not all of the data may be written 
    // in one call; write will return how many bytes were written. p keeps 
    // track of where in the buffer we are, while we decrement bytes_read 
    // to keep track of how many bytes are left to write. 
    void *p = buffer; 
    while (bytes_read > 0) 
    { 
     int bytes_written = write(sockfd, buffer, bytes_read); 
     if (bytes_written <= 0) 
     { 
      error("ERROR writing to socket\n"); 
     } 
     bytes_read -= bytes_written; 
     p += bytes_written; 
    } 
}  

printf("Done Sending the File!\n"); 
printf("Now Closing Connection.\n"); 

fclose(pf); 
close(sockfd); 
return 0; 
} 

Questo è server.c:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <signal.h> 
#include <pthread.h> 

#define SOCKET_PORT 50000 
#define filename "/home/aryan/Desktop/output.txt" 


void error(const char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 

void* client_thread_proc(void* arg) 
{ 
char buffer[256]; 
struct sockaddr_in serv_addr, cli_addr; 
int n; 
FILE *fp; 

int thisfd = (int)arg; 
printf("Server %d: accepted = %d\n", getpid(), thisfd); 

if (thisfd < 0) 
{ 
    printf("Accept error on server\n"); 
    error("ERROR on accept"); 
    return NULL; 
} 

printf("Connection %d accepted\n", thisfd); 

fp = fopen(filename, "a+b"); 
if (fp == NULL) 
{ 
    printf("File not found!\n"); 
    return NULL; 
} 
else 
{ 
    printf("Found file %s\n", filename); 
} 

/* Time to Receive the File */ 
while (1) 
{ 
    bzero(buffer,256); 
    n = read(thisfd,buffer,255); 
    if (n < 0) error("ERROR reading from socket"); 

    n = fwrite(buffer, sizeof(char), sizeof(buffer), fp); 
    if (n < 0) error("ERROR writing in file"); 

    n = write(thisfd,"I am getting your file...",25); 
    if (n < 0) error("ERROR writing to socket"); 
} /* end child while loop */ 

fclose(fp); 

return NULL; 
} 

void serve_it(int Client) 
{ 
    void* arg = (void*)Client; 
    pthread_t new_thread; 
    pthread_create(&new_thread, NULL, &client_thread_proc, arg); 
} 

/* Making Server */ 
int main() 
{ 
int sockfd, newsockfd, portno; 
socklen_t clilen; 
char buffer[256]; 
struct sockaddr_in serv_addr, cli_addr; 
int n; 
FILE *fp; 

signal (SIGCHLD, SIG_IGN); 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
    error("ERROR opening socket"); 

bzero((char *) &serv_addr, sizeof(serv_addr)); 

serv_addr.sin_family = AF_INET; 
serv_addr.sin_addr.s_addr = INADDR_ANY; 
serv_addr.sin_port = htons(SOCKET_PORT); 

if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
     error("ERROR on binding"); 

listen(sockfd,5); 

clilen = sizeof(cli_addr); 

while (1) 
{ 
    printf("Server %d accepting connections\n", getpid()); 

    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 

    serve_it(newsockfd); 
} // serving loop 


close(sockfd); 
return 0; 
} 

mi piacerebbe alcune indicazioni su come andare avanti ...
Come faccio a fare un lo script va sul file che ho ricevuto dal client al server?
Come posso inviare il nuovo file allo stesso client?
E se potessi aiutarmi con gli errori nel codice sarei grato.

Grazie a tutti voi e mi dispiace per la lunga lettura. Buona giornata!

risposta

5

primo errore:

#define filename = "Home\\Desktop\\input.txt" 

dovrebbe essere

#define filename "Home\\Desktop\\input.txt" 

Altrimenti il ​​preprocessore inserisce il

= "Home\Desktop\input.txt" 
non

il

"Home\\Desktop\\input.txt" 

che ti aspetti.

Secondo errore:

int bytes_read = read(filename /* THAT IS WRONG, FILE HANDLE MUST BE HERE */, buffer, strlen(buffer) /* also WRONG, must be MAX_BYTES_IN_BUFFER or something */); 

Qui è necessario leggere da "PF" (hai aperto con la chiamata fopen()) e l'ultimo argomento deve essere il numero di byte che si desidera leggere. Quindi se si esegue lo strlen (buffer) e il buffer contiene un po 'di spazzatura all'inizio del runtime del programma, si verificherà un arresto anomalo.strlen() deve essere chiamato solo per una stringa valida con terminazione zero, non è la dimensione dell'array!

EDIT: elaborato ciclo di server:

while (1) 
{ 
    printf("Server %d accepting connections\n", getpid()); 

    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 

    serve_it(newsockfd); 
} // serving loop 

Il serve_it():

void serve_int(int Client) 
{ 
    void* arg = (void*)Client; 
    pthread_t new_thread; 
    pthread_create(new_thread, NULL, &client_thread_proc, arg); 
} 

void* client_thread(void* arg) 
{ 
    int thisfd = (int)arg; 
    printf("Server %d: accepted = %d\n", getpid(), thisfd); 

    if (thisfd < 0) 
    { 
     printf("Accept error on server\n"); 
     error("ERROR on accept"); 
     return NULL; 
    } 

    printf("Connection %d accepted\n", thisfd); 

    fp = fopen(filename, "a+b"); 
    if (fp == NULL) 
    { 
     printf("File not found!\n"); 
     return NULL; 
    } 
    else 
    { 
     printf("Found file %s\n", filename); 
    } 

    /* Time to Receive the File */ 
    while (1) 
    { 
     bzero(buffer,256); 
     n = read(thisfd,buffer,255); 
     if (n < 0) error("ERROR reading from socket"); 

     n = fwrite(buffer, sizeof(buffer), 1, fp); 
     if (n < 0) error("ERROR writing in file"); 

     n = write(thisfd,"I am getting your file...",25); 
     if (n < 0) error("ERROR writing to socket"); 
    } /* end child while loop */ 

    return NULL; 
} 
+0

mmmm quando è stato aggiunto la risposta kinda duplicato il server.c ... potrebbe si cancella tutto? mi sto perdendo su cosa tenere e cosa non tenere ... e la mia testa sta esplodendo. – AscaL

+0

in pratica la cosa è che client_thread_proc viene ripetuto due volte, uno in main() e uno come dichiarazione di funzione (se lo si capisce correttamente, e questo è un grande se). ma se è una funzione, perché non chiamarla semplicemente? e se non lo è perché dichiararlo 2 volte? mi sto perdendo: P – AscaL

+0

C non è python, ho rimosso thread_proc da main() –

Problemi correlati