Network program doesn't seem to send the answer back the the client

Viewed 82

I am writing a client and server program, the client sends an expression in the for "num1 op num2" op being an operator. My program can receive the expression, split it, and eval, but it doesn't seem to send the answer back the the client. Do not worry about things like efficiency, most of this code was given in the assignment and doesn't need to be changed, just work.

The value of MAX is 80

Server Side:

#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <ctype.h>
#define MAX 80
#define PORT 9005
#define SA struct sockaddr

// Function designed for chat between client and server.
void func(int sockfd)
{
    char buff[MAX];
    int n, i, size;
    while (1) {
        //makes sure buffer is clear
        bzero(buff, MAX);
        // read the message from client and copy it in buffer
        size = read(sockfd, buff, sizeof(buff));
        
        long int num1, num2;
        char op;
        //splits the buff into two numbers and an operator
        sscanf(buff, "%ld %c %ld", &num1, &op, &num2);

        // print buffer which contains the client contents
        printf("From client: %ld %c %ld\n", num1, op, num2);

        //clears buffer before the server's response
        bzero(buff, MAX);
        n = 0;

        //determines operator and evaluates
        if(op == '+')
            buff[0] = num1 + num2;
        else if (op == '-')
            buff[0] = num1 - num2;
        else if(op == '*')
            buff[0] = num1 * num2;
        else if(op == '/')
            buff[0] = num1 / num2;

        // copy server message in the buffer
        //while ((buff[n++] = getchar()) != '\n');
        // and send that buffer to client
        write(sockfd, buff, sizeof(buff));

        if (strncmp("exit", buff, 4) == 0) {
            printf("Server Exit...\n");
            break;
        }
        bzero(buff, MAX);
        n = 0;
    }
}

// Driver function
int main(int argc, char *argv[]) {
    int sockfd, connfd, len;
    struct sockaddr_in servaddr, cli;

    // socket create and verification
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        printf("socket creation failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully created..\n");
    bzero(&servaddr, sizeof(servaddr));

    // assign IP, PORT
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(PORT);

    // Binding newly created socket to given IP and verification
    if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
        printf("socket bind failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully binded..\n");

    // Now server is ready to listen and verification
    if ((listen(sockfd, 5)) != 0) {
        printf("Listen failed...\n");
        exit(0);
    }
    else
        printf("Server listening..\n");
    len = sizeof(cli);

    // Accept the data packet from client and verification
    connfd = accept(sockfd, (SA*)&cli, &len);
    if (connfd < 0) {
        printf("server acccept failed...\n");
        exit(0);
    }
    else
        printf("server acccept the client...\n");

    // Function for chatting between client and server
    func(connfd);

    // After chatting close the socket
    close(sockfd);
}

Client side:

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#define MAX 80
#define PORT 9005
#define SA struct sockaddr

void func(int sockfd)
{
    char buff[MAX];
    int n;
    for (;;) {
        bzero(buff, sizeof(buff));
        printf("Enter the string : ");
        n = 0;
        while ((buff[n++] = getchar()) != '\n')
            ;
        write(sockfd, buff, sizeof(buff));
        bzero(buff, sizeof(buff));

        read(sockfd, buff, sizeof(buff));
        printf("From Server : %s\n", buff);
        //if ((strncmp(buff, "exit", 4)) == 0) {
        //    printf("Client Exit...\n");
        //    break;
        //}
    }
}

int main()
{
    int sockfd, connfd;
    struct sockaddr_in servaddr, cli;

    // socket create and varification
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        printf("socket creation failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully created..\n");
    bzero(&servaddr, sizeof(servaddr));

    // assign IP, PORT
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    servaddr.sin_port = htons(PORT);

    // connect the client socket to server socket
    if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
        printf("connection with the server failed...\n");
        exit(0);
    }
    else
        printf("connected to the server..\n");

    // function for chat
    func(sockfd);

    // close the socket
    close(sockfd);
}
1 Answers

Your client expects to read a NUL-terminated string from the server which is then printed.

        read(sockfd, buff, sizeof(buff));
        printf("From Server : %s\n", buff);

Your server tries to put the binary result of the operation into the first byte of the buffer which will not result in readable text and truncate the result in many cases.

        if(op == '+')
            buff[0] = num1 + num2;
        else if (op == '-')
            buff[0] = num1 - num2;
        else if(op == '*')
            buff[0] = num1 * num2;
        else if(op == '/')
            buff[0] = num1 / num2;

Instead of this you should convert the result to a text representation of the number, for example with sprintf.

        int result;
        if(op == '+')
            result = num1 + num2;
        else if (op == '-')
            result = num1 - num2;
        else if(op == '*')
            result = num1 * num2;
        else if(op == '/')
            result = num1 / num2;

        sprintf(buff, "%d", result);

Note that in a real application you might want to use snprintf to avoid possible buffer overflow. In your case the buffer should be big enough for a converted integer value.

Related