recv () не ждет входящих сообщений - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь написать свой собственный веб-сервер, и у меня возникла проблема с функцией recv (). Я отладил свою программу и обнаружил, что каждый раз, когда я достигаю этой строки

    if (connect(sockfd, (struct sockaddr*) &server_address, sizeof(server_address)) < 0) {
    cout << "[Client] Connection failed" << endl;
}

Я вхожу в программу на стороне сервера, и программа продолжается там. И, несмотря на это, я не отправлял сообщение со стороны клиента, функция recv () получает что-то (но это не должно работать так, верно? Recv () должен быть заблокирован, пока не пришло сообщение клиента). Я проверил это сообщение, и оно абсолютно пустое.

Моя реализация tcp-сервера:

void tcp_server::connection_handler(int socket) {
    char read_buffer[128000];
    memset(&read_buffer, 0, sizeof(read_buffer));

    while ((static_cast<size_t>(recv(socket, read_buffer, 128000, 0))) > 0) {
        cout << "[Server] Client message accepted" << endl;
        cout << "[Server] Client message: " << endl << read_buffer << endl;

        string converted_message_for_send = convert_client_message(read_buffer);

        if (send(socket, converted_message_for_send.c_str(), converted_message_for_send.size(), 0) == -1) {
            cout << "[Server] Message send failure" << endl;
        }

        cout << converted_message_for_send << endl;

        cout << "[Server] Message sent to client" << endl << endl;
        cout << "============================" << endl << endl;

        memset(&read_buffer, 0, 128000);
    }
}

void tcp_server::take_requests() {
    int client_socket;
    while (true) {
        client_socket = accept(listener_socket, (struct sockaddr*)& server_address, &socket_length);
        cout << "----------------------------" << endl << endl;
        cout << "[Server] New connection accepted" << endl << endl;
        cout << "----------------------------" << endl << endl;

        thread handling_thread(&tcp_server::connection_handler, this, client_socket);
        handling_thread.detach();
    }
}

Моя программа драйверов:

TEST_CASE("Check base read/send functions","Client") {
unsigned short int PORT = 8080;
int sockfd;
struct sockaddr_in server_address{};

sockfd = socket(AF_INET, SOCK_STREAM, 0);

memset(&server_address, '0', sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
if (inet_aton("127.0.0.1", &server_address.sin_addr) == 0) {
    cout << "[Server] Invalid IP address" << endl;
}

if (connect(sockfd, (struct sockaddr*) &server_address, sizeof(server_address)) < 0) { // im getting in server side program here while debugging
    cout << "[Client] Connection failed" << endl;
}
cout << "[Client] All setting are done" << endl;
cout << "[Client] Succefully connected to the server" << endl << endl;
cout << "----------------------------" << endl << endl;

string message = "GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1\n"
        "Host: net.tutsplus.com\n"
        "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\n"
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8*\n"
        "Accept-Language: en-us,en;q=0.5\n"
        "Accept-Encoding: gzip,deflate\n"
        "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n"
        "Keep-Alive: 300\n"
        "Connection: keep-alive\n"
        "Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\n"
        "Pragma: no-cache\n"
        "Cache-Control: no-cache\n"
        "\n";
if (write(sockfd, message.c_str(), message.size()) == -1) {
    cout << "[Client] Message sending failed" << endl;
}
cout << "[Client] Message sent to server" << endl;

char buffer[128000];

memset(&buffer, 0, 128000);
read(sockfd, buffer, 128000);

string received_message = string(buffer);

string proper_response = "HTTP/1.1 404 Not Found\n"
        "Content-Length: 26\n"
        "\n"
        "Oops! Something went wrong\n";

REQUIRE(received_message == proper_response);

cout << "[Client] Server message: " << buffer << endl;
cout << "============================" << endl << endl;

}

Итак, первая проблема: мне нужно заставить recv () ждать сообщений от клиента. И вторая проблема: когда я вхожу в программу на стороне сервера (на этапе подключения сокетов), мне нужно вернуться обратно в программу на стороне клиента (чтобы отправить сообщение от клиента).

...