0

I guess I need help again.. I am trying to establish a connection between my client and server and if it's successful the user can

1) -Input message, the message will be send to the server -the server will send a "I got your msg" back to the client. -The user can input as many messages as he/she wants until he/she has enter "Q" to go back to the main menu.

2)exit from program.

Now the problem I faced was

1)At 1.Input Message Client side - the server only reads the first message from the client input, after that it won't receive any messages, and at client side, it will striaght away exit the program after my third input and the second and third input is not send to the server.

Server Side - server does not pass back "I got your msg" to the client once it have received the message from the client.

2) and also I realized that At 1.Input Message when I press Q on my first input, It will be treated as I am sending a message to the server instead of going to back to the main menu.if I Q was my second or third input, I will do nothing and will exit the program after my third input as well

client output(base on my codes)

Main Menu!
-------------------------
1. Input Message
2. Exit
Enter your choice:
1  
Please enter the message :
a
User Input: a 
b
User Input: b
c 
User Input: c
ron@ron-VirtualBox:~/Desktop/program$ <--exit the program after third input

server output(base on my codes)

 Here is the msg: a <-- only receive first message

Now if I restart my program and just enter Q client output(base on my codes)

Main Menu!
-------------------------
1. Input Message
2. Exit
Enter your choice:
1
Please enter the message :
Q
User Input: Q
Q
User Input: Q
Q
User Input: Q
ron@ron-VirtualBox:~/Desktop/program$ <--exit the program after third input

server output(base on my codes)

 Here is the msg: Q <--treated as a message instead of going to main menu.

expected client output

Main Menu!
-------------------------
1. Input Message
2. Exit
Enter your choice:
1
Please enter the message :
a
User Input: a 
I got your msg
b
User Input: b
I got your msg
c
User Input: c
I got your msg
Q
//goes back to Main Menu after pressing Q
Main Menu!
-------------------------
1. Input Message
2. Exit
Enter your choice:

expected server output

Here is the msg: a
Here is the msg: b
Here is the msg: c

my codes(shown below)

please help me as I am really struck.thanks in advance

client.cpp

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netdb.h>
#include <stdbool.h>
#include <signal.h>
#include <iostream>
#include <sstream>
void msg(void);
void mainMenu();
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
bool loop = false; 
char options[100];
char buffer[255];
int choice;
char c;
int main(int argc, char *argv[])
{ 
    while(loop==false) {
       if (argc < 3) {
            fprintf(stderr,"usage %s hostname port\n", argv[0]);
            exit(0);
        }
         portno = atoi(argv[2]);
      /* Create a socket point */
         sockfd = socket(AF_INET, SOCK_STREAM, 0);
       if (sockfd < 0)  {
            perror("ERROR opening socket");
        exit(1);
      }
      server = gethostbyname(argv[1]);
      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);
     /* connect to the server */
     if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) {
         perror("Error connecting");
         exit(1);
     }
        mainMenu();
  }
  close(sockfd);
  return 0;
} 

void mainMenu() {
    std::cout << "\n" << std::endl;
    printf("Main Menu!\n");
    printf("-------------------------\n");
    printf(" 1. Input Message \n");
    printf(" 2. Exit \n");
    printf("Enter your choice\n");
    scanf("%d",&choice);
    getchar();
        switch(choice) {
            case 1: msg();
                    break;
            case 2: std::cout << "Exiting";
                    loop = true;
                    exit(0);
                    break;
            default:printf("%s","Invalid choice!\n");
             break;  
    }
}
void msg(void)  {
    std::cout << "Press Q to Quit" << std::endl;
    std::cout << " " << std::endl;
    /*ask for a message from the user, this message will be read by server */
    std::cout << "Please enter the message : \n" <<std::endl;       
    bzero(buffer,256);
    while(fgets(buffer,255,stdin)) {
        printf("User Input: %s",buffer);
        /* Send message to the server */
        n = write(sockfd,buffer,strlen(buffer));
        if (n < 0)  {
            perror("ERROR writing to socket");
            exit(1);
        }
    /* read server response */
        bzero(buffer,256);
        n = read(sockfd,buffer,256);
        if (n < 0)  {
            perror("ERROR reading from socket");
            exit(1);
        }
        if(strncmp(buffer,"Q",1)==0) {
            mainMenu();
        }
   }
}

from what I understand now, it's fgets that's causing it the current output now because it stops reading after a newline. so I need to change the '\n' somehow to '\0'; I tried something like this but it still not working.

void print() {
    size_t length;
    std::cout << "Please enter the message: \n" << std::endl;
    bzero(buffer,256);
    while(fgets(buffer,256,stdin)) {
            printf("User Input: %s",buffer);
            length = strlen(buffer);
            /* Send message to the server */
            if(buffer[length - 1] == '\n') {
                buffer[length -1] == '\0';
                n = write(sockfd,buffer,strlen(buffer));
            }
            if (n < 0)  {
                perror("ERROR writing to socket");
                exit(1);
            }
   }
}
7
  • 4
    It's network code with strlen() in it, so it must be buggy. Commented Nov 15, 2013 at 13:10
  • 2
    Oh look - it is. 'n = write(sockfd,buffer,strlen(buffer));' does not send the terminating null. Commented Nov 15, 2013 at 13:12
  • 1
    Also, classic #2 - 'if(n > 0)' would not indicate that a complete message has been returned into the buffer, even if the terminating null had been sent. Commented Nov 15, 2013 at 13:15
  • 1
    Closely read the man-pages for read()/write() and learn that at least for sockets those two functions do not necessarily read/write as much bytes as they were told to, but few. So looping around such calls counting until all data had been received/sent is a good idea, not to say an essential necessity. Commented Nov 15, 2013 at 14:05
  • 2
    OK, suppose the string buffer contains 'Hello\n\0' It's length, as returned by strlen(), is 6. To send this string, with it's newline and null, you need to send 7 characters, so n = write(sockfd,buffer,strlen(buffer)+1); Commented Nov 15, 2013 at 17:49

1 Answer 1

1

OK, suppose the string buffer contains 'Hello\n\0' It's length, as returned by strlen(), is 6. To send this string, with it's newline and null, you need to send 7 characters, so n = write(sockfd,buffer,strlen(buffer)+1);

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.