C++网络编程socket基础
C++网络编程socket基础
Socket编程是实现网络通信的基础。C++程序使用系统socket API构建客户端-服务器应用,支持TCP和UDP协议。
TCP服务器使用bind、listen、accept流程。
#include
#include
#include
#include
#include
#ifdef _WIN32
#include
#include
#pragma comment(lib, "ws2_32.lib")
#else
#include
#include
#include
#include
#define SOCKET int
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket close
#endif
class TCPServer {
int server_fd_;
int port_;
bool init() {
#ifdef _WIN32
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) return false;
#endif
server_fd_ = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd_ < 0) return false;
int opt = 1;
setsockopt(server_fd_, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
return true;
}
public:
TCPServer(int port) : server_fd_(-1), port_(port) {}
~TCPServer() {
if (server_fd_ >= 0) closesocket(server_fd_);
#ifdef _WIN32
WSACleanup();
#endif
}
bool start() {
if (!init()) return false;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port_);
if (bind(server_fd_, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
std::cerr << "Bind failed\n";
return false;
}
if (listen(server_fd_, 5) < 0) {
std::cerr << "Listen failed\n";
return false;
}
std::cout << "Server on port " << port_ << "\n";
return true;
}
void accept_loop() {
struct sockaddr_in client;
socklen_t client_len = sizeof(client);
while (true) {
int client_fd = accept(server_fd_, (struct sockaddr*)&client, &client_len);
if (client_fd < 0) continue;
std::cout << "Client connected: "
<< inet_ntoa(client.sin_addr) << "\n";
std::thread([client_fd]() {
char buffer[1024] = {0};
const char* response = "Hello from C++ server\n";
send(client_fd, response, strlen(response), 0);
int bytes = recv(client_fd, buffer, sizeof(buffer) - 1, 0);
if (bytes > 0) {
buffer[bytes] = '\0';
std::cout << "Received: " << buffer << "\n";
}
closesocket(client_fd);
}).detach();
}
}
};
TCP客户端连接服务器。
class TCPClient {
int sock_;
public:
TCPClient() : sock_(-1) {
#ifdef _WIN32
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
#endif
}
~TCPClient() {
if (sock_ >= 0) closesocket(sock_);
#ifdef _WIN32
WSACleanup();
#endif
}
bool connect(const std::string& host, int port) {
sock_ = socket(AF_INET, SOCK_STREAM, 0);
if (sock_ < 0) return false;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_pton(AF_INET, host.c_str(), &addr.sin_addr);
if (::connect(sock_, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
return false;
}
return true;
}
std::string receive() {
char buffer[1024] = {0};
int bytes = recv(sock_, buffer, sizeof(buffer) - 1, 0);
if (bytes > 0) {
buffer[bytes] = '\0';
return std::string(buffer);
}
return "";
}
void send_data(const std::string& data) {
send(sock_, data.c_str(), data.length(), 0);
}
};
UDP服务器。
class UDPServer {
int sock_;
public:
UDPServer(int port) {
sock_ = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
bind(sock_, (struct sockaddr*)&addr, sizeof(addr));
std::cout << "UDP server on port " << port << "\n";
}
std::string receive() {
char buffer[1024];
struct sockaddr_in client;
socklen_t len = sizeof(client);
int n = recvfrom(sock_, buffer, sizeof(buffer) - 1, 0,
(struct sockaddr*)&client, &len);
if (n > 0) {
buffer[n] = '\0';
return std::string(buffer);
}
return "";
}
~UDPServer() { closesocket(sock_); }
};
非阻塞IO设置。
void set_nonblocking(int sock) {
#ifdef _WIN32
u_long mode = 1;
ioctlsocket(sock, FIONBIO, &mode);
#else
int flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | O_NONBLOCK);
#endif
}
select多路复用。
void select_demo(int server_fd) {
fd_set readfds;
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(server_fd, &readfds);
int activity = select(server_fd + 1, &readfds, nullptr, nullptr, &tv);
if (activity < 0) {
std::cerr << "Select error\n";
} else if (activity == 0) {
std::cout << "Timeout\n";
} else {
if (FD_ISSET(server_fd, &readfds)) {
std::cout << "New connection available\n";
}
}
}
HTTP服务器简单实现。
void http_response(int client_fd) {
const char* response =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: close\r\n"
"\r\n"
"
Hello from C++
";
send(client_fd, response, strlen(response), 0);
}
网络编程是构建分布式系统和网络服务的基础。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)