JPery / MJPEGWriter

Lightweight HTTP server to stream your OpenCV processing in C++
MIT License
97 stars 40 forks source link

Socket: is accepting nonexistent connection #4

Closed Otamay closed 5 years ago

Otamay commented 5 years ago

Hi, I'm compiling for raspbian and the program works but socket "accept" command is returning -1 as soon as it is reached. One hot fix is to move all open() code to Listener() (before loop), maybe there is a problem with sharing resources between threads?

This is my working code:

void
MJPEGWriter::Listener()
{
    fd_set rread;
    SOCKET maxfd;
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    // SOCKADDR_IN address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);
    if (::bind(sock, (SOCKADDR*)&address, sizeof(address)) == SOCKET_ERROR)
      {
    cerr << "error : couldn't bind sock " << sock << " to port " << port << "!" << endl;
    return;
      }
    if (listen(sock, NUM_CONNECTIONS) == SOCKET_ERROR)
      {
    cerr << "error : couldn't listen on sock " << sock << " on port " << port << " !" << endl;
    return;
      }
    cout << "Listening on socket " << sock << " on port " << port << "..." << endl;
    FD_SET(sock, &master);
    // cout << "Master: " << master << endl;

    while (true)
    {
        rread = master;
        struct timeval to = { 0, timeout };
        maxfd = sock + 1;
        int sel = select(maxfd, &rread, NULL, NULL, &to);
        if (sel > 0) {
            for (int s = 0; s < maxfd; s++)
            {
                if (FD_ISSET(s, &rread) && s == sock)
                {
            sockaddr_in client_addr;
                    socklen_t         client_addr_len = sizeof(client_addr);
                    // SOCKADDR_IN address = { 0 };
                    SOCKET      client = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len);
                    if (client == SOCKET_ERROR)
                    {
                        cerr << "error : couldn't accept connection on sock " << sock << " !" << endl;
                        return;
                    }
                    maxfd = (maxfd>client ? maxfd : client);
                    pthread_mutex_lock(&mutex_cout);
                    cout << "new client " << client << endl;
                    pthread_mutex_unlock(&mutex_cout);
                    pthread_mutex_lock(&mutex_client);
                    _write(client, (char*)"HTTP/1.0 200 OK\r\n", 0);
                    _write(client, (char*)
                        "Server: Mozarella/2.2\r\n"
                        "Accept-Range: bytes\r\n"
                        "Connection: close\r\n"
                        "Max-Age: 0\r\n"
                        "Expires: 0\r\n"
                        "Cache-Control: no-cache, private\r\n"
                        "Pragma: no-cache\r\n"
                        "Content-Type: multipart/x-mixed-replace; boundary=mjpegstream\r\n"
                        "\r\n", 0);
                    clients.push_back(client);
                    pthread_mutex_unlock(&mutex_client);
                }
            }
        }
        usleep(1000);
    }
}
JPery commented 5 years ago

Could you include this issue as a Pull Request? Thank you.

JPery commented 5 years ago

I think a simpler way to do it could be calling this->open(port) in the method Listener() before the while(true) statement.

JPery commented 5 years ago

Should be fixed in #5