Thread: File Server Help

  1. #1
    C/C++ Learner & Lover
    Join Date
    Aug 2008
    Location
    Argentina
    Posts
    193

    File Server Help

    Well.. im triying to do a fileserver that handles multiple connections.. but i'm having lots of problems.. i really need a hand.. here's the code
    I have simplified the code so it would be more easy to execute withouth having problems..

    This is the client..

    Code:
    #include <stdio.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #define DEST_PORT 3000
    #define DEST_IP 127.0.0.1
    
    int i;
    //password check has been removed due it always says its correct &#172;&#172; //ignore this
    int passwdcheck(int *sock) {
    char password[]="lol";
    char i;
    char buff[30];
    recv(*sock, buff, sizeof(buff), 0);
    if(!strcmp(password, buff)) {
    send(*sock, 0, sizeof(i), 0);
    return 0;
    }
    else {
    send(*sock, 1, sizeof(i), 0);
    return 1;
    }
    }
    
    long fsize(const char *const name)
    {
    struct stat stbuf;
    if(stat(name, &stbuf) == -1)
    return -1; // The file could not be accessed.
    return stbuf.st_size;
    }
    
    void sendfile(int *sock) {
    FILE *file;
    int parts;
    char haslastpart;
    int lastpart;
    char filepath[30];
    char filesend[]="filetransfer";
    printf("Filename");
    scanf( "&#37;s", filepath );
    send(*sock, filesend, sizeof(filesend), 0);
    if(file=fopen(filepath,"rb")) {
      long filesize;
      filesize = fsize(filepath);
      if(filesize>=1048576) {
        parts=filesize/1048576;
        if(lastpart=filesize%1048576 != 0) { //ignore this
        haslastpart=1;  //ignore this
        ++parts;  //ignore this
        send(*sock, parts, sizeof(parts), 0);
        }
        else {
          send(*sock, parts, sizeof(parts), 0);
        }
      }
      else {
        int fileparts=1;
        send(*sock, fileparts, sizeof(fileparts), 0);
      }
      for(i=0;i<parts;i++) {
      char *buff;
      fread(buff, 1048576, 1, file);
      send(*sock, buff, 1048576, 0);
      }
    }
    
    }
    
    int main() {
    char password[]="lol";
    struct sockaddr_in serveraddr, dest_addr;
    int sock; //sock
    /* client buffer */
    char buf[1024]; //mucho buffer papa
    int nbytes;
    /* for setsockopt() */
    int addrlen;
    int i, j;
    int yes = 1;
    /* creating socket*/
    if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Server-socket() error lol!");
    exit(1);
    }
    printf("Socket Creado\n");
    /* testing if addr is beeing used */
    if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    perror("Server-setsockopt() error lol!");
    exit(1);
    }
    printf("test reusando adress\n");
    dest_addr.sin_family = AF_INET;          // host byte order
    dest_addr.sin_port = htons(DEST_PORT);   // short, network byte order
    dest_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    memset(dest_addr.sin_zero, '\0', sizeof dest_addr.sin_zero);
    
    printf("Conectando\n");
    if(!connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr))) { 
    exit(1);
    }
    printf("Conectado..\n");
    send(sock, password, strlen(password), 0);
    int buf2;
    //password check has been removed due it always says its correct &#172;&#172;
    printf("Password ok..\n");
    while(1) {
    //this loop is not beeing executed =S
      printf("Sendifle\n");
      sendfile(&sock);
    }
    
    }
    This is the server..

    Code:
    #include <stdio.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #define QUEQUE_SIZE 100
    #define LOCALPORT 3000
    
    struct settings {
            char password[20];
            int port;
            } settings;
    
    int passwdcheck(int *sock) {
    char password[]="lol";
    char i;
    char buff[30];
    recv(*sock, buff, sizeof(buff), 0);
    if(!strcmp(password, buff)) {
    send(*sock, 0, sizeof(i), 0);
    return 0;
    }
    else {
    send(*sock, 1, sizeof(i), 0);
    return 1;
    }
    }
    
    void recievefile(int *sock) {
    FILE *file;
    char filepath[]="mothe........a.txt";
    int fileparts;
    char i;
    recv(*sock, fileparts, sizeof(fileparts), 0);
    if(file=fopen(filepath,"ab")) {
      for(i=0;i<fileparts;i++) {
         char *buff;
         recv(*sock, buff, 1048576, 0);
         if(fwrite(buff, 1048576, 1, file) == -1) {
           printf("Error writing file %s in part: %i", filepath, &i); //prototipo
         }
         else {
           //Archivo recibido en..
         }
      fclose(file);
      }
    }
    else {
    
    }
    }
    
    int main() {
    fd_set master, read_fds;
    struct sockaddr_in serveraddr, clientaddr;
    int fdmax; //numero maximo de file descriptor
    int listener; //sock a listenear
    int newfd; //sock nuevo al accept()
    
    /* client buffer */
    char buf[1024]; //mucho buffer
    int nbytes;
    /* for setsockopt() */
    int yes = 1;
    int addrlen;
    int i, j;
    /* clearing the sets */
    FD_ZERO(&master);
    FD_ZERO(&read_fds);
    /* creating socket listener for listen() */
    if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Server-socket() error lol!");
    exit(1);
    }
    printf("Socket Creado\n");
    /* testing if addr is beeing used */
    if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    perror("Server-setsockopt() error lol!");
    exit(1);
    }
    /* bind data */
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = INADDR_ANY;
    serveraddr.sin_port = htons(LOCALPORT);
    memset(&(serveraddr.sin_zero), '\0', 8);
    /* bind */
    if(bind(listener, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) {
    perror("Server-bind() error lol!");
    exit(1);
    }
    printf("Port 3000 bindeado\n");
    /* listenando */
    if(listen(listener, 10) == -1) {
    perror("Server-listen() error lol!");
    exit(1);
    }
    printf("Socket Listeneando\n");
    /*adding listener to the master set  */
    FD_SET(listener, &master);
    
    fdmax = listener;
    /* loop */
    for(;;) {
    /* copy */
    read_fds = master;
    /* starts select */
      if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
      perror("Server-select() error lol!");
      exit(1);
      }
      printf("Select starteado\n");
      for(i = 0; i <= fdmax; i++) {
        if(FD_ISSET(i, &read_fds)) {
          if(i == listener) { /* nueva conexion */
            addrlen = sizeof(clientaddr);
            if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1) {
              perror("Server-accept() error lol!");
            }
            printf("Nueva conexion.. testeando pass\n");
          if(passwdcheck(&newfd) == 1) {
            FD_SET(newfd, &master);
            printf("Password correcta\n");
            if(newfd > fdmax){ /* keep track of the maximum */
              fdmax = newfd;
            }
          }
          else {
            close(newfd);
            printf("Password incorrecta\n");
          }
        }
        else {
          if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) { /* deals with connections */
            if(nbytes == 0) {
              close(i);
              FD_CLR(i, &master);
              printf("Conexion perdida\n");
            }
            else {
              recievefile(&i);
            }
          }
        }
    
      }
    }
    }
    return 0;
    /* fin funcion */
    }
    Last edited by lautarox; 09-07-2008 at 10:19 AM.

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Code:
    //password check has been removed due it always says its correct
    int passwdcheck(int *sock) {
    	char password[]="lol";
    	char i;
    	char buff[30];
    	recv(*sock, buff, sizeof(buff), 0);
    	if(!strcmp(password, buff)) {
    		/* It's unlikey that the memory at location 0 has the message you want to send. */
    		send(*sock, 0, sizeof(i), 0);
    		return 0;
    	}
    	else {
    		/* same here, except for memory location 1. */ 
    		send(*sock, 1, sizeof(i), 0);
    		return 1;
    	}
    }

  3. #3
    C/C++ Learner & Lover
    Join Date
    Aug 2008
    Location
    Argentina
    Posts
    193
    How can i send an integer with sockets?

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    send(*sock, &an_int, sizeof(an_int), 0);

    I don't think this accounts for byte-order though.

  5. #5
    C/C++ Learner & Lover
    Join Date
    Aug 2008
    Location
    Argentina
    Posts
    193
    mmm what about storing the recieved buff into a char pointer is that posible? i mean, like this
    char * pointer;
    recv(socket, pointer, 1024, 0);

  6. #6
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Quote Originally Posted by lautarox View Post
    mmm what about storing the recieved buff into a char pointer is that posible? i mean, like this
    char * pointer;
    recv(socket, pointer, 1024, 0);
    That points to nothing. It doesn't have to be a direct pointer like that anyways.

    Code:
    char buffer[1024];
    recv(socket, buffer, sizeof(buffer), 0);
    But yes you can do it the way you did it if "pointer" was actually pointing to something that is larger or equal to 1024 bytes.

  7. #7
    C/C++ Learner & Lover
    Join Date
    Aug 2008
    Location
    Argentina
    Posts
    193
    Cause i have seen somewhere that the pointers where used to store strings like this, char *pointer ="data";

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You can do that if you initialize it right away, as you have done in the example right here. But a naked pointer declaration like char *pointer doesn't allocate any memory.

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Remember that recv might not fill the buffer, so check the return value.

  10. #10
    C/C++ Learner & Lover
    Join Date
    Aug 2008
    Location
    Argentina
    Posts
    193
    What if it doesn't fill the buffer?
    And.. what about the pointers? are they valid?

  11. #11
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    > What if it doesn't fill the buffer?

    Then you have a partially filled buffer. What are you asking here?

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Are you aware of the existence of man pages?
    Quote Originally Posted by man recv
    the receive calls normally return any data available, up to
    the requested amount, rather than waiting for receipt of the full amount
    requested; this behavior is affected by the socket-level options
    SO_RCVLOWAT and SO_RCVTIMEO described in getsockopt(2).
    The pointers are yours, so it's your job to see that they're valid. (That is, recv neither tries to get memory to put the data in, nor tries to return unused memory.)

  13. #13
    C/C++ Learner & Lover
    Join Date
    Aug 2008
    Location
    Argentina
    Posts
    193
    I mean, I have the function with the arguments like this int passwdcheck(int *sock); and I should call it passwdcheck(&sock) ? and using the pointer like this send(*sock, 0, sizeof(i), 0); is that ok?

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Code:
    send(*sock, 0, sizeof(i), 0);
    Yes and no.

  15. #15
    C/C++ Learner & Lover
    Join Date
    Aug 2008
    Location
    Argentina
    Posts
    193
    Yeah, i've actually repaired that xD, but I'm still having a problem, I'm using a select for the connections, but.. when i recieve an already connected client's file the function doesn't work.
    And what about the size and the lenght when sending trough sockets? i have seen both of them when setting the size
    And another question, I've made a loop for recieving the file, if another client would want to upload a file at the same time, it would have to wait right?
    Last edited by lautarox; 09-09-2008 at 05:53 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need Help Fixing My C Program. Deals with File I/O
    By Matus in forum C Programming
    Replies: 7
    Last Post: 04-29-2008, 07:51 PM
  2. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  3. archive format
    By Nor in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 08-05-2003, 07:01 PM
  4. socket question
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 07-19-2002, 01:54 PM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM