2012-06-27 7 views
5

En primer lugar, gracias a todos por leer esto y ayudar, estoy muy agradecido.
Segundo, lo siento, pero sigo siendo nuevo en este sitio y el inglés no es mi idioma materno, así que podría hacer algunos errores de formateo y lenguaje. Me disculpo de antemano.
Además, mi conocimiento de C no es tan bueno, pero estoy dispuesto a aprender y mejorar.
Ahora, para el asunto en cuestión:Enviando y recibiendo un archivo (Servidor/Cliente) en C usando socket en Unix

Lo que tengo que hacer es crear un cliente y un servidor, y hacer que el servidor escuche las conexiones entrantes.
Luego hago que el Cliente envíe un archivo de texto bastante grande (sé que solo será UN archivo) al Servidor.
El servidor realizará algunas operaciones en el archivo (ejecutará un script en el archivo enviado que produce otro archivo en la salida llamada "output.txt"). El servidor deberá enviar el archivo output.txt de vuelta al Cliente.

Ahora, tengo un poco de cómo hacer un cliente y un servidor (leo la guía de beej y algunas otras cosas en este sitio), incluso aunque probablemente cometí algunos errores. Necesito ayuda con el servidor que recibe el archivo, luego llama al script y envía el otro archivo al cliente. Por ahora lo que hice fue el Servidor y el Cliente ... Realmente no sé cómo continuar.
En una nota lateral, hice estos archivos usando lo que encontré en este sitio y en Internet, espero que no sean demasiado complicados, ya que no soy tan bueno como programador.

Ésta es 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; 
} 

Ésta es 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; 
} 

me gustaría algunos consejos sobre cómo pasar ...
¿Cómo puedo hacer una script ir en el archivo que recibí de cliente a servidor?
¿Cómo envío el nuevo archivo al mismo cliente?
Y si pudiera ayudarme con los errores en el código, le agradecería.

Gracias a todos y perdón por la larga lectura. ¡Que tengas un buen día!

Respuesta

5

primer error:

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

debería ser

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

lo contrario, el preprocesador inserta el

= "Home\Desktop\input.txt" 
no

la

"Home\\Desktop\\input.txt" 

que espera.

Segundo error:

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

Aquí se debe leer de "PF" (que ha abierto con la llamada fopen()) y el último argumento debe ser el número de bytes que desea leer. Entonces, si haces el strlen (buffer) y el buffer contiene algo de basura al comienzo del tiempo de ejecución del programa, obtendrás un crash.strlen() solo debe llamarse a una cadena válida terminada en cero, ¡no es el tamaño de la matriz!

EDIT: elaborado bucle de servidor:

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

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

    serve_it(newsockfd); 
} // serving loop 

El 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 cuando agregó su respuesta ha duplicado un poco la server.c ... ¿podría aclararlo? Me estoy perdiendo en lo que debo conservar y lo que no debo mantener ... y mi cabeza está explotando. – AscaL

+0

básicamente, el problema es que client_thread_proc se repite dos veces, una en la declaración main() y otra en función (si la entiendes correctamente, y eso si es grande). pero si es una función, ¿por qué no solo llamarla? y si no es así, ¿por qué declararlo 2 veces? Me estoy perdiendo: P – AscaL

+0

C no es python, he eliminado el thread_proc de main() –

Cuestiones relacionadas