Я пытаюсь написать свой собственный веб-сервер, и у меня возникла проблема с функцией 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 () ждать сообщений от клиента. И вторая проблема: когда я вхожу в программу на стороне сервера (на этапе подключения сокетов), мне нужно вернуться обратно в программу на стороне клиента (чтобы отправить сообщение от клиента).