server upd
added python client
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
const uint32_t k_max_message_size = 4096;
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "net_util.hpp"
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
int32_t read_full(int connectionfd, void* buf, size_t len) {
|
||||
auto buffer = static_cast<char*>(buf);
|
||||
while (len > 0) {
|
||||
ssize_t rv = ::read(connectionfd, buffer, len);
|
||||
if (rv == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (rv < 0) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
buffer += rv;
|
||||
len -= static_cast<size_t>(rv);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t write_all(int connectionfd, const void* buf, size_t len) {
|
||||
auto* buffer = static_cast<const char*>(buf);
|
||||
while (len > 0) {
|
||||
ssize_t rv = ::write(connectionfd, buffer, len);
|
||||
if (rv <= 0) {
|
||||
if (rv < 0 && errno == EINTR) continue;
|
||||
return -1;
|
||||
}
|
||||
buffer += rv;
|
||||
len -= static_cast<size_t>(rv);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int32_t read_full(int connectionfd, void* buf, size_t len);
|
||||
int32_t write_all(int connectionfd, const void* buf, size_t len);
|
||||
+57
-16
@@ -1,9 +1,20 @@
|
||||
#include "server.hpp"
|
||||
#include <iostream>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "server.hpp"
|
||||
#include "net_util.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
|
||||
Server::Server(const Config& config)
|
||||
: address(config.get_address()), port(config.get_port()), sockfd(-1) {
|
||||
@@ -43,18 +54,41 @@ void Server::setup() {
|
||||
std::cout << "Server started on " << address << ":" << port << "\n";
|
||||
}
|
||||
|
||||
void Server::handle_connection(int connectionfd) {
|
||||
char rbuf[64] = {};
|
||||
ssize_t n = read(connectionfd, rbuf, sizeof(rbuf) - 1);
|
||||
if (n < 0) {
|
||||
std::cerr << "Error reading client packet\n";
|
||||
return;
|
||||
int32_t Server::handle_connection(int connectionfd) {
|
||||
std::cout << "Waiting for data from " << connectionfd << "\n";
|
||||
|
||||
uint32_t len_net = 0;
|
||||
errno = 0;
|
||||
if (read_full(connectionfd, &len_net, sizeof(len_net)) != 0) {
|
||||
print_error(errno == 0 ? "EOF from client" : "Error reading length");
|
||||
return -1;
|
||||
}
|
||||
std::cout << "Client says: " << std::string(rbuf, n) << "\n";
|
||||
ssize_t written = write(connectionfd, "Hello, client!\n", 14);
|
||||
if (written < 0) {
|
||||
std::cerr << "Error writing to client\n";
|
||||
|
||||
uint32_t len = ntohl(len_net);
|
||||
|
||||
if (len > k_max_message_size) {
|
||||
print_error("Message length is too long");
|
||||
std::cerr << len << " > " << k_max_message_size << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string message(len, '\0');
|
||||
if (len > 0) {
|
||||
if (read_full(connectionfd, message.data(), len) != 0) {
|
||||
print_error("Error reading payload");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Client says: " << message << "\n";
|
||||
|
||||
const std::string reply = "world";
|
||||
uint32_t reply_len_net = htonl(static_cast<uint32_t>(reply.size()));
|
||||
|
||||
if (write_all(connectionfd, &reply_len_net, sizeof(reply_len_net)) != 0) return -1;
|
||||
if (write_all(connectionfd, reply.data(), reply.size()) != 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Server::run() {
|
||||
@@ -67,7 +101,14 @@ void Server::run() {
|
||||
if (connectionfd < 0) {
|
||||
continue;
|
||||
}
|
||||
handle_connection(connectionfd);
|
||||
std::cout << "Accepted connection from " << connectionfd << "\n";
|
||||
while (true) {
|
||||
int32_t err = handle_connection(connectionfd);
|
||||
if (err) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::cout << "Closing connection from " << connectionfd << "\n";
|
||||
close(connectionfd);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include "config.hpp"
|
||||
|
||||
class Server {
|
||||
@@ -15,6 +16,6 @@ private:
|
||||
std::string address;
|
||||
int port;
|
||||
|
||||
void handle_connection(int connectionfd);
|
||||
int32_t handle_connection(int connectionfd);
|
||||
void setup();
|
||||
};
|
||||
|
||||
@@ -7,3 +7,7 @@ void stop_program(int signum) {
|
||||
std::cout << "Exiting program...\n";
|
||||
exit(signum);
|
||||
}
|
||||
|
||||
void print_error(const std::string& msg) {
|
||||
std::cerr << msg << ": " << std::strerror(errno) << "\n";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <string>
|
||||
|
||||
void stop_program(int signum);
|
||||
void print_error(const std::string& msg);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user