0

I try to write simple linux app that will accept http requests. I want to be able to stop listening thread so I use select().

Call sequence is

socket()->setsockopt()->bind()->listen()->select()->accept()->read()

When I send request from Chrome I get 451 bytes long buffer. Then select() immediately returns with success as well as accept() as if another request came. And then `read()' stops the thread waiting, because it has nothing to read.

socket() ok. listenSocket:3
bind() ok

listen() ok
select() got ready connection
accept() ok. socket: 4
reading...
read() ok. NRead: 451

listen() ok
select() got ready connection
accept() ok. socket: 5
reading...

What I do wrong?

What articles/books are worth to read to learn socket programming?

Best wishes, Yura

Here is the simplified code:

void doServer()
{
    const int trueFlag = 1;

    m_socketListen = socket(AF_INET, SOCK_STREAM, 0);
    // check m_socketListen

    nRetVal = setsockopt(m_socketListen, SOL_SOCKET, SO_REUSEADDR, &trueFlag, sizeof(int));
    // check

    struct sockaddr_in addrServer;
    bzero((char*)&addrServer, sizeof(addrServer));

    addrServer.sin_family = AF_INET;
    addrServer.sin_port = htons(DEFAULT_HTTP_PORT);
    addrServer.sin_addr.s_addr = INADDR_ANY;

    nRetVal = bind(m_socketListen, (const struct sockaddr* )&addrServer, sizeof(addrServer));
    // check

    struct sockaddr_in addrClient;
    while (true)
    {
        bzero((char*)&addrClient, sizeof(addrClient));
        unsigned int addrSize = sizeof(addrClient);

        nRetVal = listen(m_socketListen, SOMAXCONN);
        // check

        struct timeval timeout;
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        fd_set set;
        FD_ZERO (&set);
        FD_SET (m_socketListen, &set);

        nRetVal = select (FD_SETSIZE, &set, NULL, NULL, &timeout);
        // check

        if (FD_ISSET(m_socketListen, &set))
        {
            int clientSocket = accept(m_socketListen,
                                        (struct sockaddr*)&addrClient,
                                            &addrSize);

            int NRead;
            char buffer[BUF_SIZE];
            bzero(&buffer, BUF_SIZE);

            NRead = read(clientSocket, &buffer, BUF_SIZE);

            std::cout << "read() ok. NRead: " << NRead << std::endl;
        }
    }
}
Yura
  • 969
  • 14
  • 33
  • Read documentation https://www.systutorials.com/docs/linux/man/2-recv/ pay attention to MSG_DONTWAIT flag – Slava Apr 30 '18 at 14:34
  • "What articles/books are worth to read to learn socket programming?" Such questions are off topic, with the 1 exception (for c++) https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – UKMonkey Apr 30 '18 at 14:53
  • Got it. Sorry, won't do this again – Yura Apr 30 '18 at 14:56
  • `read(sock, &buffer, BUF_SIZE);` Don't you mean to read from the new socket; rather than `sock` whatever that is – UKMonkey Apr 30 '18 at 14:57
  • `while (true)` you only want to loop around the accept and reads; the listening has already been done – UKMonkey Apr 30 '18 at 14:59
  • Thanks, @UKMonkey, it was the mistake. In real project I check the stop flag and process new socket in a separate thread. I didin't want to post long listing – Yura Apr 30 '18 at 15:01
  • @Slava, thanks fot the recv() - now it works ok but I still have the problem: when I receive all the message from the connection socket, listening select() that waits for the new connection becomes ready again, accept() returns a new socket where there's no connection. Why does it happen? – Yura May 01 '18 at 11:47

0 Answers0