feat: 封装了 TCP Socket 连接层并通过测试
This commit is contained in:
+1
-1
@@ -10,5 +10,5 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static -g -O2")
|
|||||||
|
|
||||||
add_subdirectory(${PROJECT_SOURCE_DIR}/include/ouc_server)
|
add_subdirectory(${PROJECT_SOURCE_DIR}/include/ouc_server)
|
||||||
|
|
||||||
add_executable(test "${PROJECT_SOURCE_DIR}/examples/epoll_tcp_loop.cpp")
|
add_executable(test "${PROJECT_SOURCE_DIR}/examples/test_tcp_socket.cpp")
|
||||||
target_link_libraries(test PRIVATE ouc_server_lib)
|
target_link_libraries(test PRIVATE ouc_server_lib)
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include <socket/tcp_socket.hpp>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
using namespace ouc_server::ouc_socket;
|
||||||
|
|
||||||
|
auto server = TCPSocket::create();
|
||||||
|
if (!server.bind("127.0.0.1", 8080))
|
||||||
|
{
|
||||||
|
perror("socket");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!server.listen())
|
||||||
|
{
|
||||||
|
perror("listen");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
puts("Server listening on port 8080...");
|
||||||
|
|
||||||
|
auto client = server.accept();
|
||||||
|
while (client.get_fd() < 0)
|
||||||
|
{
|
||||||
|
client = server.accept();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
}
|
||||||
|
puts("Client conntected");
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
ssize_t n = client.recv(buf, sizeof(buf));
|
||||||
|
|
||||||
|
if (n <= 0)
|
||||||
|
continue;
|
||||||
|
if (!memcmp("exit", buf, 4))
|
||||||
|
break;
|
||||||
|
|
||||||
|
std::string data(buf, n);
|
||||||
|
std::cout << "Receive data: " << data;
|
||||||
|
|
||||||
|
// client.send("Receive!: ");
|
||||||
|
// client.send(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
client.close();
|
||||||
|
server.close();
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#include <socket/tcp_socket.hpp>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
namespace ouc_server
|
||||||
|
{
|
||||||
|
namespace ouc_socket
|
||||||
|
{
|
||||||
|
TCPSocket::TCPSocket(int fd)
|
||||||
|
: listen_fd(fd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPSocket::TCPSocket(TCPSocket &&other)
|
||||||
|
: listen_fd(other.listen_fd)
|
||||||
|
{
|
||||||
|
other.listen_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPSocket &TCPSocket::operator=(TCPSocket &&other)
|
||||||
|
{
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
if (listen_fd >= 0)
|
||||||
|
close();
|
||||||
|
listen_fd = other.listen_fd;
|
||||||
|
other.listen_fd = -1;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPSocket TCPSocket::create()
|
||||||
|
{
|
||||||
|
int fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
perror("socket");
|
||||||
|
|
||||||
|
int opt = 1;
|
||||||
|
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||||
|
return TCPSocket(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TCPSocket::bind(const std::string &ip, uint16_t port)
|
||||||
|
{
|
||||||
|
sockaddr_in addr{};
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
if (inet_pton(AF_INET, ip.c_str(), &addr.sin_addr) != 1)
|
||||||
|
return false;
|
||||||
|
return ::bind(listen_fd, (sockaddr *)&addr, sizeof(addr)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TCPSocket::listen(int backlog) { return ::listen(listen_fd, backlog) == 0; }
|
||||||
|
|
||||||
|
TCPSocket TCPSocket::accept()
|
||||||
|
{
|
||||||
|
int client_fd = ::accept4(listen_fd, nullptr, nullptr, SOCK_NONBLOCK);
|
||||||
|
if (client_fd < 0)
|
||||||
|
return TCPSocket();
|
||||||
|
return TCPSocket(client_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TCPSocket::close() { return ::close(listen_fd) == 0; }
|
||||||
|
|
||||||
|
ssize_t TCPSocket::send(const char *buf, size_t len) { return ::send(listen_fd, buf, len, 0); }
|
||||||
|
|
||||||
|
ssize_t TCPSocket::send(const char *buf) { return this->send(buf, sizeof(buf)); }
|
||||||
|
|
||||||
|
ssize_t TCPSocket::recv(void *buf, size_t len) { return ::recv(listen_fd, buf, len, 0); }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef INCLUDE_OUC_SERVER_TCP_SOCKET
|
||||||
|
#define INCLUDE_OUC_SERVER_TCP_SOCKET
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ouc_server
|
||||||
|
{
|
||||||
|
namespace ouc_socket
|
||||||
|
{
|
||||||
|
class TCPSocket
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int listen_fd;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TCPSocket(int = -1);
|
||||||
|
|
||||||
|
TCPSocket(const TCPSocket &) = delete;
|
||||||
|
TCPSocket &operator=(const TCPSocket &) = delete;
|
||||||
|
|
||||||
|
TCPSocket(TCPSocket &&);
|
||||||
|
TCPSocket &operator=(TCPSocket &&);
|
||||||
|
|
||||||
|
static TCPSocket create();
|
||||||
|
|
||||||
|
public:
|
||||||
|
int get_fd() const { return listen_fd; }
|
||||||
|
|
||||||
|
bool bind(const std::string &, uint16_t);
|
||||||
|
bool listen(int = 128);
|
||||||
|
TCPSocket accept();
|
||||||
|
bool close();
|
||||||
|
|
||||||
|
public:
|
||||||
|
ssize_t send(const char *, size_t);
|
||||||
|
ssize_t send(const char *);
|
||||||
|
ssize_t recv(void *, size_t);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // INCLUDE_OUC_SERVER_TCP_SOCKET
|
||||||
Reference in New Issue
Block a user