Thread: Basic C Socket Program Client/Server text file content transmission! DESPERATE HELP!!

  1. #16
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    Quote Originally Posted by MK27 View Post
    It is better to use send() and recv() than read() and write(). There's not much difference, just send() and recv() are intended for networking, are more portable, and have a bit more functionality.
    Ok. I'll change them over.

    Quote Originally Posted by MK27 View Post
    Hopefully you can see the value of transmitting the length. Then you can just use a (fairly small) fixed size buffer, which you recv upto that size. Once you have the length, you malloc another buffer for the data, copy the first bunch in, then keep looping length/bufsize times (plus the length%bufsize remainder!) and strcat into your malloc'd data pointer.
    I just want to make sure I'm following here...

    By the spec sheet, the client only enters in the persons name they want to view details about. So the client will enter "Name", it's only a last name, not a first and last. They send this over to the server.

    Now, are you saying I should do a function call on the server side calculating the length of the string then send that with the string? This sounds silly, so I don't think this is what you mean, unless I am missing the point of doing this....

    At the moment, the server receives a buffer of 255 characters with the users input inside. It's only going to be a name, maximum of 50 characters. Why must I worry about this any more?

    Once I'm on the server side and I have the buffer with the name passed, can't I just use it from there and perform server side code to find the matching information associated with the name passed? Sorry if I'm misunderstanding but I'm not quite sure of the importance of the server receiving the length of the string the client sends.

    I'd really love if you could clear up my confusion ><

    Thanks again

  2. #17
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    Ok, I haven't stopped working on this....

    I made a new program to search through a text file and output the line it finds the answer into an array of chars...

    The test program I made worked before I put it into the socket code. Basically, what my function does is:

    - Get given a string as a char*
    - Checks the file for that string in each line
    - Returns the contents of the first line that string was found in as a char*

    This was the code for my program:

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int findName(char* clientSearch, char* serverResult);
    
    int main()
    {
      char search[256] = {"Billy"};
      char result[256];
      findName(search, result);
      printf("The string is: %s", result);
      return 1;
    }
    
    int findName(char* clientSearch, char* serverResult)
    {
      FILE *filename=fopen("NAMES.TXT","r");
      char temp[256];
      bzero(temp,256);
      while (filename!=NULL && fgets(temp, sizeof(temp),filename) != NULL)
        {
          if (strstr(temp, clientSearch))
    	{
    	  printf("temp is: %s", temp);
    	  strncpy(serverResult,temp, sizeof(temp));
    	  return 1;
    	}
        }
      if (filename!=NULL) fclose(filename);
      return 0;
    }
    So this worked with no problems, it would go into my text file, find Billy and print to screen:

    Billy Brown 18

    or whatever was on that line that Billy was in.

    (I understand this algorithm needs work, as it might produce bad results if the name is found somewhere else other than at the start of the line etc etc, but i'm going to fix that later)

    So...

    I now stuck this into my socket code (the findName function)... but the output I'm getting is gibberish.

    It seems like it can't find a match for what is in buffer, because I put some debugging code and asked for it to print to screen when it went into the STRSTR if loop (meaning it found the string in that line of the text file).

    Here is the code:

    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    void errormsg(char *message) // Error message function
    {
      perror(message); // Show user error message
      exit(1);         // exit
    }
    
    int findName(char* clientSearch, char* serverResult)
    {
      FILE *filename=fopen("NAME.TXT","r");
      char temp[256];
      while (filename!=NULL && fgets(temp, sizeof(temp),filename) != NULL)
        {
          if (strstr(temp, clientSearch))
    	{
    	  printf("temp is: %s", temp);
    	  strncpy(serverResult,temp, sizeof(temp));
    	}
        }
      if (filename!=NULL) fclose(filename);
      return -1;
    }
    
    int main (int argc, char *argv[])
    {
      int sockd;       // file descriptor for socket
      int newsockd;     // file descriptor for new socket
      int portnum;       // port number for transmissions
      int clientlength;  // length of client address
      int retval;        // return value
      
      char buffer[256];  
      char searchresult[256];
      
      struct sockaddr_in serv_addr, cli_addr;  // structure defined in netinet header file.
      
      if (argc < 2)     // Server must be initiated with a port.
        {
          fprintf(stderr,"Usage:./server Port \n");
          exit(1);
        }
      
      sockd = socket(AF_INET, SOCK_STREAM, 0); // AF_INET for internet domain, Stream Socket
      
      if (sockd == -1)
        error("ERROR: Opening socket failed");
    
      bzero((char *) &serv_addr, sizeof(serv_addr)); // Set all vals in serv_addr to zero
      
      portnum = atoi(argv[1]); // Gets user input and stores as port number
      serv_addr.sin_family = AF_INET; // Sets serv_addr in struct sock_addr_in
      serv_addr.sin_port = htons(portnum);  // change the port number from host to server format
      serv_addr.sin_addr.s_addr = INADDR_ANY;   // contains IP address of host
    
      // bind socket to address, cast serv_addr to type struct sockaddr
      if (bind(sockd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
        error("ERROR: Bind failed"); // present error if it returns -1 (fails)
    
      listen(sockd,5); // allow p to 5 connections that can wait while process handles an existing connection.
    
      clientlength = sizeof(cli_addr); // set clientlength variable to the length of client address
      // set reference to client address and length of client address
      newsockd = accept(sockd, (struct sockaddr *) &cli_addr, &clientlength);
      if (newsockd < 0)
        error("ERROR: couldn't establish connection with client");
    
      // bzero(buffer,256);  // zero the buffer values
      retval = read(newsockd,buffer,255); // store the new socket file description into the buffer
      if (retval < 0)
        error("ERROR: could not read new socket file description");
      printf("Message received from client is: %s", buffer); // show users output
    
      findName(buffer,searchresult);
      printf("Result is %s", searchresult);
      
      retval = write(newsockd, searchresult, 18);
      if (retval < 0)
        error("ERROR: could not write to socket");
      
      // Send string to user there ^
    
      return 0;
    }
    Like I said before, I added in some debug code, just asking it to print out to the screen when it entered the str str if statement and it never got there. It just printed out some gibberish (black squares with question marks inside). I'm pretty sure it's not finding a match for what's in buffer and what's in the text file.

    I am sending from the client the word "Billy". It is appearing on the server side "Message recieved from client: Billy" but then it just spits out The result is: gibberish black squares...

    Like I said, I'm pretty sure it's something to do with buffer, that it can't find Billy because maybe buffer contains other stuff in it?

    Is there something I can do to clear buffer? Or is the problem lying somewhere else?

    Any help is GREATLY appreciated!!!!!!!

    I really don't have much time I hope someone can help me...

  3. #18
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    just to narrow it down

    Code:
    int findName(char* clientSearch, char* serverResult)
    {
      FILE *filename=fopen("NAME.TXT","r");
      char temp[256];
      while (filename!=NULL && fgets(temp, sizeof(temp),filename) != NULL)
        {
          if (strstr(temp, clientSearch))
    	{
    	  printf("temp is: %s", temp);
    	  strncpy(serverResult,temp, sizeof(temp));
    	}
        }
      if (filename!=NULL) fclose(filename);
      return -1;
    }
    It never enters the if statement above where I have printf...

    here is where the buffer gets its data ...

    Code:
     // bzero(buffer,256);  // zero the buffer values
      retval = read(newsockd,buffer,255); // store the new socket file description into the buffer
      if (retval < 0)
        error("ERROR: could not read new socket file description");
      printf("Message received from client is: %s", buffer); // show users output
    
      findName(buffer,searchresult);
      printf("Result is %s", searchresult);
    I'm getting Result is blah blah gibberish black squares.... I know that what I'm sending from the client is in my text file, I also know that it works when I don't have this in the socket program and I make my own char DATA[255] = { "Billy" }

    Any Ideas?

  4. #19
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I suppose your file has Billy in it on a line? If so you are trying to match Billy\n against Billy, and failing to do so.

  5. #20
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    Quote Originally Posted by tabstop View Post
    I suppose your file has Billy in it on a line? If so you are trying to match Billy\n against Billy, and failing to do so.
    That's the thing... If I make a char* at the top of my main function like this:

    Code:
    char* test[256] = {"Billy"};
    
    findName(test, searchresult);
    It works fine and it searches through the text file and finds "Billy" and out puts Billys line which is:

    Billy Brown 18

    It has something to do with what Buffer contains, when I printf buffer, it just says Billy...

    but I'm sure it's containing something else after that maybe some left over stuff from newsockd or something... what can I do to make sure that basically the buffer array of chars contains only the name, similar to when I just declare an array like above (in the code snippit).

    Any ideas?

    Again, help is VERY appreciated!

    Thanks!

  6. #21
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    Ok, it's definitely that buffer contains stuff in it after the name that I don't want...

    Because if I do this...

    Code:
    char* test
    
    strncpy(test, buffer, 5);
    findName(test, searchresult);
    it solves the problem aswell, so basically I just need to know how to clear the buffer after the string the client entered was...

    it would be fine if I knew the length of what the user typed in, because then I could just do the fix i did above... but I don't know the length that they are going to type...

    Any ideas?

    Thanks again!

  7. #22
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Desperatenoob View Post
    That's the thing... If I make a char* at the top of my main function like this:

    Code:
    char* test[256] = {"Billy"};
    
    findName(test, searchresult);
    It works fine and it searches through the text file and finds "Billy" and out puts Billys line which is:

    Billy Brown 18

    It has something to do with what Buffer contains, when I printf buffer, it just says Billy...

    but I'm sure it's containing something else after that maybe some left over stuff from newsockd or something... what can I do to make sure that basically the buffer array of chars contains only the name, similar to when I just declare an array like above (in the code snippit).

    Any ideas?

    Again, help is VERY appreciated!

    Thanks!
    Right, because in the example that works you are searching for "Billy" which is contained in the target text and everybody's happy. In this example you are searching for "Billy\n", which is not contained in the target text and is therefore not found. When reading from a file, you need to strip the new-line characters yourself. (This is true for any file and is not really related to sockets.)

  8. #23
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    Ok, I understand... What is the best way to strip the \n?

    I am currently just doing this:

    Code:
    buffer[strnlen(buffer)-1] = NULL;
    It is working, but is that what you meant by striping it?

  9. #24
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    By the way, thanks for your help tab please excuse my noob mistakes.

  10. #25
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is how I remove the all newlines from the buffer

    Code:
    int i;
    
    i = sizeof(buffer);
    while(i >= 0) {
      if(buffer[i] == '\n')
        buffer[i] = '\0');
      --i;
    }
    Good luck DN!

  11. #26
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    Ok...

    After hours of playing with this thing I've got a system that works with a few flaws I need to iron out.

    At the moment, my program does the following on client side:

    Please enter a name:
    (user enters in name, eg. Billy)

    (server) Billy Brown 19

    Prompts the user for another name to query or q to quit.

    On server side:

    Receives client input

    Prints client input to screen

    Searches text file, returns last line that contains the string the client sent.


    Sends the char array containing the last line to the client.

    ----------------------------

    The problem I'm having is when the user quits, the server outputs:

    Message received:

    so it receives a blank message when the client exits...

    I'll hop on my linux machine shortly and post the code so I can show where the error is.

    Basically, when the user enters q, I don't do a write() call, and just exit()...

    Is there a call I need to do after connecting that tells the server to break the connection and that the client isn't actually sending anything?

  12. #27
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Desperatenoob View Post
    I just want to make sure I'm following here...
    By the spec sheet, the client only enters in the persons name they want to view details about. So the client will enter "Name", it's only a last name, not a first and last. They send this over to the server.
    Now, are you saying I should do a function call on the server side calculating the length of the string then send that with the string? This sounds silly, so I don't think this is what you mean,
    That is what I meant -- but I thought you were sending an entire text file of some length (sorry, I didn't read the OP). So you could see where a problem would arise:
    Code:
    recv(sock, buf, 255, 0);  /* hmmm, that's not the whole file */
    If you make it a rule that the first 4 bytes of every transmission is the transmission length, this is easier to deal with. One thing NOT to do with networking is to presume a message is complete -- the underlaying socket interface can do this:

    - send 42 bytes
    - interruption
    - send some more

    This can lead to garbled messages if you simply loop around and accept what ever is ready to read. However, to be honest, I would not worry about that here.

    It is close to a no-op tho -- ie, doing this will not slow anything down, it is just a matter of adding those bits of code.

    Quote Originally Posted by Desperatenoob View Post
    Basically, when the user enters q, I don't do a write() call, and just exit()...

    Is there a call I need to do after connecting that tells the server to break the connection and that the client isn't actually sending anything?
    Well, your 40 hours is probably up, but you should do a write at exit to tell the server you are disconnecting:
    Code:
    send(sock,"<DISCONNECT>",12,0);
    Then you need something like this early in the server parsing loop:
    Code:
    if (strstr, buf, "<DISCONNECT>") [close connection]
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  13. #28
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    Awesome, thanks MK

    And I still have 23 hours...

    Things are looking good, just have to clean it up a little and format the string so it prints nicely.

    I have one thing I'm a bit stuck on... Getting the information (which is tab delimited) to format correctly, I'll probably post code a bit later if I still can't get this out.

    Thanks again MK, the DISCONNECT thing is exactly what I was looking for (can't believe I didn't think of it actually, really simple ><)!

  14. #29
    Registered User
    Join Date
    Oct 2009
    Posts
    1
    Just had to register to say this sounds identical to the assignment Im doing at the moment thats due today. Does it have anything to do with Cricket by any chance? Good luck with it. I feel your pain.

  15. #30
    Registered User
    Join Date
    Oct 2009
    Posts
    20
    Quote Originally Posted by Muskstick View Post
    Just had to register to say this sounds identical to the assignment Im doing at the moment thats due today. Does it have anything to do with Cricket by any chance? Good luck with it. I feel your pain.
    perhaps... haha, now don't copy my code!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 09-16-2009, 06:00 AM
  2. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  3. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM
  4. Problems displaying content of a text file
    By melissa in forum C++ Programming
    Replies: 5
    Last Post: 11-12-2001, 06:13 PM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM