6

First and foremost, thank you all for reading this and helping, I'm very grateful.
Second I'm sorry but i'm still new to this site and English is not my mother language so I could do some formatting and language mistakes. I apologize in advance.
Also, my C knowledge is not that good, but i'm willing to learn and improve.
Now, to the matter at hand:

What I need to do is to create a Client and a Server, and have the server listen for incoming connections.
Then I have the Client send a quite big text file (I know it will only be ONE file) to the Server.
The Server will then do some operation on the file (it will run a script on the sent file that produces another file in output called "output.txt"). The server then will need to send the output.txt file back to the Client.

Now, I kinda got how to make a Client and a Server (I read beej guide and some other stuff on this site), even tho I probably made some mistakes. I need some help with the server reciving the file, then calling the script and sending the other file back to the client. For now what I did is the Server and Client... I don't really know how to go on.
On a side note, I made this files using what I found on this site and on the internet, I hope they are not too messy, as I'm not that good of a programmer.

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

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

I'd like some pointers on how to go on...
How do I make a script go on the file i received from client to server?
How do I send the new file back to the same client?
And if you could help me with the errors in the code i'd be grateful.

Thank you all and sorry for the long read. Have a nice day!

aroonav
  • 85
  • 7
AscaL
  • 183
  • 3
  • 3
  • 11

1 Answers1

5

First error:

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

should be

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

Otherwise the preprocessor inserts the

= "Home\Desktop\input.txt"

not the

"Home\\Desktop\\input.txt"

that you expect.

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

Here you must read from "pf" (you've opened it with the fopen() call) and the last argument must be the number of bytes you want to read. So if you do the strlen(buffer) and the buffer contains some garbage at the beginning of the program's runtime you will get a crash. strlen() must only be called for valid zero-terminated string, it is not the size of the array !

EDIT: elaborated server's loop:

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

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

    serve_it(newsockfd);
}  // serving loop

The 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;
}
Viktor Latypov
  • 14,289
  • 3
  • 40
  • 55
  • mmmm when you added your answer you kinda duplicated the server.c... could you clear it up? i'm getting lost on what to keep and what not to keep... and my head is exploding. – AscaL Jun 27 '12 at 18:22
  • basically the thing is that client_thread_proc is repeated two times, one in the main() and one as function declaration (if u understand it correctly, and that's a big if). but if it is a funcion why not just call it? and if it isn't why declare it 2 times? i'm getting lost :P – AscaL Jun 27 '12 at 18:36
  • kk :) thx that had me confused :P now it gives me /tmp/ccG381x5.o: In function `serve_it': server.c:(.text+0x21a): undefined reference to `pthread_create' collect2: ld returned 1 exit status... why can't this work for once :P i also edited server.c to replicate the file i have at this moment. and thanks again! – AscaL Jun 27 '12 at 18:51
  • oh sorry man, i don't know how to do that... i use gcc -o server server.c to compile it, if i try gcc -lpthread server server.c it does not work, nor gcc -o -lpthread server server.c – AscaL Jun 27 '12 at 19:13
  • i'm reading a tutorial on threads and i tried to compile with gcc -lpthread server.c but still gives me an error: gcc -lpthread server.c /tmp/ccBduiJx.o: In function `serve_it': server.c:(.text+0x21a): undefined reference to `pthread_create' collect2: ld returned 1 exit status – AscaL Jun 27 '12 at 19:28
  • if you are tired of doing this we can continue another day, it's no problem for me :). Let me know and thx a lot for the help! – AscaL Jun 27 '12 at 19:45
  • Hey, i kinda made the transfer work, i'd like a hand with the code tho because there is a mistake in the sending or receiving loop and i really can't find it. I opened a new question here http://stackoverflow.com/questions/11254447/file-transfer-server-client-in-c-on-linux-using-socket if you could look it up and tell me what you think i'd really apriciate it! thx a lot. – AscaL Jun 29 '12 at 14:06