Thread: client is only receiving one line of information

  1. #1
    Registered User
    Join Date
    Jul 2010
    Posts
    178

    client is only receiving one line of information

    Can someone please show me what I need to do in order fix this problem? I am trying to get all the information without depressing the return key. Here is a "screenshot" of what I am having a problem with.
    Code:
    Recieved data = Server is Ready 
    SEND (q or Q to quit) : 1
    
    Recieved data = Enter Department Name 
    SEND (q or Q to quit) : Math
    
    Recieved data = Math 102 
    SEND (q or Q to quit) : 
    
    Recieved data = Math 420 
    SEND (q or Q to quit) :
    Here is my client side:
    Code:
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    
    #define BUF 2048
    
    int main()
    
    {
    
            int sock, bytes_received;
            char send_data[BUF],recv_data[BUF];
            struct hostent *host;
            struct sockaddr_in server_addr;
    
            host = gethostbyname("134.124.30.128");
    
            if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                perror("Socket");
                exit(1);
            }
    
            server_addr.sin_family = AF_INET;
            server_addr.sin_port = htons(13018);
            server_addr.sin_addr = *((struct in_addr *)host->h_addr);
            bzero(&(server_addr.sin_zero),8);
    
            if (connect(sock, (struct sockaddr *)&server_addr,
                        sizeof(struct sockaddr)) == -1)
            {
                perror("Connect");
                exit(1);
            }
    
            while(1)
            {
              bytes_received = recv(sock, recv_data, BUF, 0);
              recv_data[bytes_received] = '\0';
    
              if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
              {
               close(sock);
               break;
              }
    
               else
               printf("\nRecieved data = %s " , recv_data);
    
               printf("\nSEND (q or Q to quit) : ");
               gets(send_data);
    
              if (strcmp(send_data , "q") != 0 && strcmp(send_data , "Q") != 0)
               send(sock,send_data,strlen(send_data), 0);
    
              else
              {
               send(sock,send_data,strlen(send_data), 0);
               close(sock);
               break;
              }
    
            }
    return 0;
    }
    and what I believe is the relevant server code:
    Code:
    #include "classes.h"
    
    int main(void)
    {
    
        int switchInput;
        int i = 0;
        int connected;
        int sock;
        int bytes_received;
        int sin_size;
        int true = 1;
        int tempCourse = 0;
        char send_data[BUF];
        char recv_data[BUF];
        char tempDept[5];
        char tempDay[2];
        char tempTime[2];
        FILE *filePointer;
        sched_record data[MAX_RECORD];
        filePointer = fopen (BINFILE, "rb");
    
        if ((sock = socket (AF_INET, SOCK_STREAM, 0)) == -1) {
            perror ("Socket");
            exit(1);
            }
    
        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)) == -1) {
            perror ("Setsocketopt");
            exit(1);
            }
    
        self.sin_family = AF_INET;
        self.sin_port = htons(13018);
        bzero(&(self.sin_zero), 8);
        self.sin_addr.s_addr = inet_addr ("134.124.30.128");
    
        if (bind (sock, (struct sockaddr *)(&self), sizeof (self)) < 0) {
            perror ("Unable to bind");
            exit(1);
            }
    
        if (listen(sock, 5) == -1) {
            perror("Listen");
            exit(1);
        }
    
        if (filePointer == NULL) {
                perror("**Can't open file**");
                exit(1);
            }
    
        printf("\nTCPServer waiting for client on port 13018");
            fflush(stdout);
    
         while(1) {
    
            sin_size = sizeof(struct sockaddr_in);
            connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
    
            printf("\n I got a connection from (%s, %d)",
                   inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
            printf("\n");
    
            char send_data[] = "Server is Ready";
            send(connected, send_data, strlen(send_data), 0);
    
            while(1) {
    
                bytes_received = recv(connected, recv_data, BUF, 0);
                recv_data[bytes_received] = '\0';
                switchInput = atoi (recv_data);
    
    
                switch(switchInput) {
    
                case 1:
    
                    fread(data, sizeof(sched_record), MAX_RECORD, filePointer);
                    fclose(filePointer);
                    char send_data[] = "Enter Department Name";
                    send(connected, send_data, strlen(send_data), 0);
                    bytes_received = recv(connected, recv_data, BUF, 0);
                    recv_data[bytes_received] = '\0';
                    strcpy(tempDept, recv_data);
                    for (i=0; i<MAX_RECORD; i++){
                        if ((strcmp(tempDept, data[i].Dept)==0) && tempCourse != data[i].course){
                                sprintf(send_data,"%s %d", data[i].Dept, data[i].course);
                                send(connected, send_data, strlen(send_data), 0);
                                tempCourse = data[i].course;
    
                        }
                    }
                break;
                
                 case 2:
    
                    fread(data, sizeof(sched_record), MAX_RECORD, filePointer);
                    fclose(filePointer);
                    char send_data_1[] = "Enter Department Name";
                    send(connected, send_data_1, strlen(send_data_1), 0);
                    bytes_received = recv(connected, recv_data, BUF, 0);
                    recv_data[bytes_received] = '\0';
                    strcpy(tempDept, recv_data);
                    char send_data_2[] = "Enter Course Number";
                    send(connected, send_data_2, strlen(send_data_2), 0);
                    bytes_received = recv(connected, recv_data, BUF, 0);
                    recv_data[bytes_received] = '\0';
                    tempCourse = atoi (recv_data);
                    qsort(data, MAX_RECORD, sizeof(sched_record), sortFunction);
                    for (i=0; i < MAX_RECORD; i++){
                        if ((strcmp(tempDept, data[i].Dept)==0) && tempCourse == data[i].course){
                            sprintf(send_data, "%s %d %d %2s %02d%02d %02d%02d %s", data[i].Dept, data[i].course, data[i].sect,
                                    data[i].meet_days == MW ? "MW" : "TR", data[i].start.hour, data[i].start.min, data[i].end.hour, data[i].end.min,
                                    data[i].instr);
                            send(connected, send_data, strlen(send_data), 0);
                        }
                    }
                break;
    This is the last thing I need to figure out and I have been at it all day. I would really appreciate it if someone can show me. Thank You!

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
     gets(send_data);
    Gets is evil! Never, ever use it again! Read this: FAQ > Why gets() is bad / Buffer Overflows - Cprogramming.com. Try using fgets (just remember to strip the newline). More info on that here: FAQ > Get a line of text from the user/keyboard (C) - Cprogramming.com.

    As for not wanting to have to press enter, you don't have an easy option. Standard input (i.e. the keyboard, where gets and scanf get their info from) is line buffered by default. That means data doesn't go from the keyboard to your program until you press enter. This saves a lot of hassle dealing with things like backspace. Without it, every program would have to erase the previous character and redisplay the input line itself. Also, it saves communication between the terminal/keyboard and your program.

    There is no completely portable solution, so it depends on what OS this is running on. In *nix, you can play with the termios library, in Windows, I have no idea. A slightly more "heavy-handed" approach might be to use a curses library (e.g. ncurses, pdcurses), which allow for fully unbuffered input, but there's a bit more code involved than some simple printf calls.

  3. #3
    Registered User
    Join Date
    Jul 2010
    Posts
    178
    Quote Originally Posted by anduril462 View Post
    Code:
     gets(send_data);
    Gets is evil! Never, ever use it again! Read this: FAQ > Why gets() is bad / Buffer Overflows - Cprogramming.com. Try using fgets (just remember to strip the newline). More info on that here: FAQ > Get a line of text from the user/keyboard (C) - Cprogramming.com.

    As for not wanting to have to press enter, you don't have an easy option. Standard input (i.e. the keyboard, where gets and scanf get their info from) is line buffered by default. That means data doesn't go from the keyboard to your program until you press enter. This saves a lot of hassle dealing with things like backspace. Without it, every program would have to erase the previous character and redisplay the input line itself. Also, it saves communication between the terminal/keyboard and your program.

    There is no completely portable solution, so it depends on what OS this is running on. In *nix, you can play with the termios library, in Windows, I have no idea. A slightly more "heavy-handed" approach might be to use a curses library (e.g. ncurses, pdcurses), which allow for fully unbuffered input, but there's a bit more code involved than some simple printf calls.
    Will change the fgets thanks. What I meant on the depressing the enter key is the infor above,
    Code:
    Math 102
    Math 420
    can either be on the same line or a seperate line. In order to get Math 420, I have to depress the enter key and wondering if there is a way I can get that info in one stream, not seperate streams.
    Last edited by csharp100; 05-03-2012 at 04:51 PM.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    It's all in the same stream (i.e. it's all coming from stdin or whatever), but you want it to work regardless of a new line. You could just type "Math 102 Math 420" with spaces between each part. scanf ignores whitespace, including new lines, when used with the %s (string) specifier. That wont work though if your department will have a space in it, such as "Computer Science". Note if you have several records on the same line, it may be difficult to tell them apart unless there is always exactly two fields per record and they fit a fairly consistent format. I seem to recall from your other thread yesterday you had 4 fields, including time and day or something. Handling them as optional chars may be tough if it's all on one line, or there is no delimiter character (e.g. no newline).

  5. #5
    Registered User
    Join Date
    Jul 2010
    Posts
    178
    Quote Originally Posted by anduril462 View Post
    It's all in the same stream (i.e. it's all coming from stdin or whatever), but you want it to work regardless of a new line. You could just type "Math 102 Math 420" with spaces between each part. scanf ignores whitespace, including new lines, when used with the %s (string) specifier. That wont work though if your department will have a space in it, such as "Computer Science". Note if you have several records on the same line, it may be difficult to tell them apart unless there is always exactly two fields per record and they fit a fairly consistent format. I seem to recall from your other thread yesterday you had 4 fields, including time and day or something. Handling them as optional chars may be tough if it's all on one line, or there is no delimiter character (e.g. no newline).
    Actually the Math 102 and Math 420 is what the server is sending. I'm not typing anything. The only thing I am typing on the client side is Math, the server is sending the Math 102 and Math 420. It is working through a for loop and doing its comparison for what it is looking for. Then sending it one at a time it seems. I am not sure how I would go about fixing that. BTW thanks for taking the time with me.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Just use sscanf to parse apart the data you get in recv_data, probably the %s and %d modifiers will be what you want. Check the return value to make sure it parsed correctly.

    Remember when working with sockets, send and recv are not guaranteed to write/read all the bytes you asked it to, it may do less. That means you have to be sure you aren't trying to process a string like "Math 102 Mat".

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 01-27-2010, 01:20 AM
  2. Client/server problem; server either stops receiving data or client stops sending
    By robot-ic in forum Networking/Device Communication
    Replies: 10
    Last Post: 02-16-2009, 11:45 AM
  3. Client application having problem receiving from server side?
    By dp_76 in forum Networking/Device Communication
    Replies: 2
    Last Post: 08-04-2005, 02:58 PM
  4. Client not receiving FD_CLOSE notification message?
    By dp_76 in forum Networking/Device Communication
    Replies: 2
    Last Post: 05-22-2005, 11:08 PM
  5. receiving problems in network chat client
    By chris285 in forum C++ Programming
    Replies: 5
    Last Post: 01-11-2005, 05:10 AM