Click here to Skip to main content
15,919,931 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am working on socket programming and I am facing problem with time out used before read() It always going to ret=0 condition and not proceeding ahead although client giving data
This is server.c file
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <sys/select.h>
#include <sys/fcntl.h>
#include <sys/time.h>

#define BACKLOG 3

void error(const char *ptr);
/*Global Variables*/
int sockfd = 0, newsockfd = 0;
int ret = 0;
void call(char *ptr)
{
    FILE *fp;
    char arr[100] = {'\0'};
    fp = popen(ptr, "r");
    while (1)
    {
        fread(arr, sizeof(arr), 1, fp);
        write(newsockfd, arr, sizeof(arr));
        if (feof(fp) == 1)
        {
            sleep(1); //used to change priority
                      /*If i am not using sleep() than the client goes into blocking and waiting for server*/
            write(newsockfd, "quit", sizeof("quit"));
            break;
        }
    }
    pclose(fp);
}

void _close()
{
    printf("closing the connection");
    ret = close(newsockfd);
    if (ret < 0)
        error("close");
    ret = close(sockfd);
    if (ret < 0)
        error("close");
    exit(0);
}

void handler(int _catch)
{
    printf("received signal of %d\n", _catch);
    _close();
}

int main(int argc, char *argv[])
{
    int port = 0;
    int socklen = 0;
    int i = 0, j = 0;
    int ret1 = 0;
    char buff[255];
    char cmp_str[] = {"quit"};
    char string[100] = {"\0"};
    char *retptr = NULL;
    struct sockaddr_in server_addr, client_addr;
    clock_t start, end;
    if (argc < 2)
    {
        printf("Please give the port address\n");
        exit(1);
    }
    socklen = sizeof(client_addr);

    /*Taking port address*/
    port = atoi(argv[1]);

    /**Creating a socket**/
    sockfd = socket(PF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("socket");

    /** sockaddr**/
    server_addr.sin_family = AF_INET;                /* Internet address family for IPv4*/
    server_addr.sin_addr.s_addr = (htonl)INADDR_ANY; /*Any incoming interface*/
    server_addr.sin_port = htons(port);              /*Local port*/

    /**Bind the socket**/
    ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0)
        error("bind");

    /**listen**/
    ret = listen(sockfd, BACKLOG);
    if (ret < 0)
        error("listen");

    /**accept function**/
    newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &socklen);
    if (newsockfd < 0)
        error("accept");

    /*Signal Handling*/
    signal(SIGINT, handler);

    /*Communication*/
    fcntl(newsockfd, F_SETFL, O_NONBLOCK); // set to non-blocking
    fcntl(newsockfd, F_SETFL, O_ASYNC);    // set to asynchronous I/O

    system("clear");

    /*read*/
    bzero(buff, sizeof(buff));

    ret = read(newsockfd, (void *)buff, sizeof(buff));
    /*ret1 = select(BACKLOG, &readfds, NULL, NULL, &timeout);
    if (ret == 0)
    {
        printf("time out\n");
        _close();
    }*/
    if (ret < 0)
        perror("read");
    printf("Client :- %s", buff);

    call("ls | grep txt");

    /*Read the query*/
    bzero(buff, sizeof(buff));
    int opt = 3;
    setsockopt(newsockfd, SOL_SOCKET, SO_RCVLOWAT, &opt, sizeof(opt));

    /*For Time out connection*/
    fd_set readfds;
    FD_ZERO(&readfds);
    FD_SET(0, &readfds);
    struct timeval timeout;
    timeout.tv_sec = 10; //seconds//
    timeout.tv_usec = 0; //micro seconds//

    ret=select(1, &readfds, NULL, NULL, &timeout);
    if (ret==0)
    {
        printf("time out\n");
        _close();
    }
    else if(ret>0)
    {
        ret = read(newsockfd, (void *)buff, sizeof(buff));
        if (ret < 0)
            perror("read");
        if (ret1 == 0)
        {
            printf("time out\n");
            _close();
        }
        printf("Client :- %s", buff);

        /*transfering the file*/
        strncpy(string, "cat", strlen("cat"));
        for (i = 0; string[i] != '\0'; i++)
            ;
        string[i] = ' ';
        i++;
        for (i, j = 0; buff[j] != '\0'; j++, i++)
        {
            string[i] = buff[j];
        }
        call(string);
        _close();
    }
}
void error(const char *ptr)
{
    perror(ptr);
    exit(1);
}


What I have tried:

Searched and read articles but no solution get
Posted
Updated 27-Jul-18 5:53am

1 solution

IIRC, read() and write() may be used for blocking socket I/O. If you want non-blocking I/O, use send() and recv(). Also note that in order to receive data, your server must either use a polling loop (which wastes CPU time), or use select().

Beej's Guide to Network Programming[^] is a very good introduction to all aspects of socket programming. It also contains pointers to more advanced topics, should you need them.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900