I am new to socket programming and 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.

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

roberts@roberts-VirtualBox:~/Desktop/program$ <--exit the program after third input

server output(base on my codes)

Here is the msg: a

Now if I restart my program and just enter Q
client output

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
roberts@roberts-VirtualBox:~/Desktop/program$ <--exit the program after third input

server output

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

Main Menu!
-------------------------
1. Input Message
2. Exit
Enter your choice:

expected server ouput

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.

One last thing, I apologize because my codes is mixed with c and c++ style of codings.
will be changing it to c++ way and thus will be looking for a solution more towards c++.

thanks in advance

server.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 <stdbool.h>

void doPrcoessing(int sock) {
    int n;
    char buffer[255];
    bzero(buffer,256);
    n =read(sock,buffer,255);

    if(n < 0) {
        perror("Error from reading socket");
        exit(1);
    }

    if(n > 0) {
        printf("Here is the msg: %s\n",buffer);
        n=write(sock,"I got your msg",18);
    }

    if(n<0) {
        perror("Error writing to socket");
        exit(1);
    }
}

int main( int argc, char *argv[] )
{
    int sockfd,pid,newsockfd,portno,clientn;
    struct sockaddr_in serv_addr,cli_addr;
    char buffer[256];
    bool connected;
    int n;
    socklen_t len;

    /*call socket() function*/
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0)
    {
    perror("Error opening socket");
    exit(1);
    }
   // printf("socket retrieve success\n");

   /*Initialize socket structure*/

    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    /*bind the host address using bind() call*/
    if(bind(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
    perror("Error on binding!");
    exit(1);
    }
    int yes =1;
    if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes, sizeof(yes)) == -1) {
    perror("setsockopt");
    exit(1);
    }
    /*start listening for clients, will go into sleep mode and wait for incoming connection*/
    listen(sockfd,5);
    len = sizeof(cli_addr);  

     while(connected == false) {
        newsockfd = accept(sockfd,(struct sockaddr*)&cli_addr,&len);

        if(newsockfd < 0) {
            perror("Error on accept!");
            exit(1);
            }

        /*Create chlid process*/
        pid =fork();
        if(pid < 0)
        {
            perror("Error on fork!");
            exit(1);
        }
        if(pid == 0)
        {
            /*Client process*/
            close(sockfd);
            doPrcoessing(newsockfd);
            return 0;   
        }
        else
        {
            close(newsockfd);
        }
    }
    return 0;
}

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();
            }
    }
}

Edited 3 Years Ago by johnson_2

Not sure what your problem is. Are you trying to accomplish something like this?

server.c

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>

#define DEFAULT_PROTOCOL 0
#define PORT 50000
#define MSG "\nGot the message!\n"

int main(int argc, char**argv)
{
    int listenfd, connfd, val = 1;
    char recvline[BUFSIZ + 1];
    struct sockaddr_in servaddr;

    signal(SIGCHLD, SIG_IGN);

    if ((listenfd = socket(AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL)) < 0)
    {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if ((bind(listenfd, (const struct sockaddr*)&servaddr, sizeof(servaddr))) < 0)
    {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    if ((listen(listenfd, 5)) < 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    for (;;)
    {
        connfd = accept(listenfd, NULL, NULL);

        if (fork())
        {
            close(connfd);
        }
        else
        {
            int n = 0, i = 0;

            close(listenfd);

            while ((n = read(connfd, &recvline[i], (BUFSIZ - i))) > 0)
            {
                i += n;
            }
            recvline[i] = '\0';

            fprintf(stdout, "Server rec'd->%s\n", recvline);
            write(connfd, MSG, strlen(MSG));

            close(connfd);
            exit(EXIT_SUCCESS);
        }
    }

    exit(EXIT_SUCCESS);
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <errno.h>

#define DEFAULT_PROTOCOL 0
#define PORT 50000
#define MSG "This is the message\n"

int main(int argc, char**argv)
{
    int clientfd, tot = 0, n = 0;
    char recvline[BUFSIZ + 1], rsp;
    struct sockaddr_in servaddr;

    if ( argc != 2 )
    {
        fputs("Usage error - a.out <IPaddress>\n", stderr);
        exit(EXIT_FAILURE);
    }

    while ( true )
    {
        fputs("Do you want to send a msg?(y/n)->", stdout);
        fscanf(stdin, "%c", &rsp);

        if ( rsp == 'n' ) break;

    if ((clientfd = socket(AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL)) < 0)
    {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);

    if ((inet_pton(AF_INET, argv[1], &servaddr.sin_addr.s_addr)) <= 0)
    {
        fputs("Conversion error!\n", stderr);
        exit(EXIT_FAILURE);
    }

    if ((connect(clientfd, (const struct sockaddr*)&servaddr, sizeof(servaddr))) < 0)
    {
        perror("connect");
        exit(EXIT_FAILURE);
    }

    write(clientfd, MSG, strlen(MSG));

    shutdown(clientfd, SHUT_WR);

    while ((n = read(clientfd, recvline, BUFSIZ)) > 0)
    {
        recvline[n] = '\0';
        tot += n;
        fputs(recvline, stdout);
    }
    if ( n < 0 )
        fputs("Read error!\n", stdout);
    fprintf(stdout, "Client read %d bytes!\n", tot);
    close(clientfd);
    }
    exit(EXIT_SUCCESS);
}

thanks alot for your great help. I guess I will review your codes.

This article has been dead for over six months. Start a new discussion instead.