您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
在C++中,使用Socket库进行网络编程时,通常需要一个事件循环来处理客户端和服务器之间的通信
以下是一个简单的基于Socket库的事件循环示例:
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
class EventLoop {
public:
EventLoop() : stop_(false) {
worker_ = std::thread(&EventLoop::run, this);
}
~EventLoop() {
{
std::unique_lock<std::mutex> lock(mutex_);
stop_ = true;
}
cond_.notify_one();
if (worker_.joinable()) {
worker_.join();
}
}
void add_socket(int sockfd) {
std::unique_lock<std::mutex> lock(mutex_);
sockets_.push_back(sockfd);
}
void remove_socket(int sockfd) {
std::unique_lock<std::mutex> lock(mutex_);
sockets_.erase(std::remove(sockets_.begin(), sockets_.end(), sockfd), sockets_.end());
}
void run() {
while (true) {
std::vector<int> read_sockets;
std::vector<int> write_sockets;
{
std::unique_lock<std::mutex> lock(mutex_);
cond_.wait(lock, [this] { return !sockets_.empty() || stop_; });
for (int sockfd : sockets_) {
int events = 0;
if (FD_ISSET(sockfd, &read_fds_)) {
events |= POLLIN;
}
if (FD_ISSET(sockfd, &write_fds_)) {
events |= POLLOUT;
}
if (events) {
read_sockets.push_back(sockfd);
}
}
}
for (int sockfd : read_sockets) {
handle_read(sockfd);
}
for (int sockfd : write_sockets) {
handle_write(sockfd);
}
}
}
private:
void handle_read(int sockfd) {
char buffer[1024];
ssize_t n = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
if (n > 0) {
buffer[n] = '\0';
std::cout << "Received from " << sockfd << ": " << buffer << std::endl;
} else if (n == 0) {
remove_socket(sockfd);
close(sockfd);
} else {
perror("recv");
remove_socket(sockfd);
close(sockfd);
}
}
void handle_write(int sockfd) {
const char* message = "Hello, World!";
ssize_t n = send(sockfd, message, strlen(message), 0);
if (n > 0) {
remove_socket(sockfd);
close(sockfd);
} else {
perror("send");
remove_socket(sockfd);
close(sockfd);
}
}
std::thread worker_;
std::vector<int> sockets_;
std::mutex mutex_;
std::condition_variable cond_;
bool stop_;
fd_set read_fds_;
fd_set write_fds_;
};
int main() {
EventLoop loop;
int server_sock = socket(AF_INET, SOCK_STREAM, 0);
if (server_sock == -1) {
perror("socket");
return 1;
}
struct sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(8080);
if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
perror("bind");
return 1;
}
if (listen(server_sock, 10) == -1) {
perror("listen");
return 1;
}
struct sockaddr_in client_addr = {0};
socklen_t client_addr_size = sizeof(client_addr);
int client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_addr_size);
if (client_sock == -1) {
perror("accept");
return 1;
}
loop.add_socket(client_sock);
loop.run();
close(client_sock);
close(server_sock);
return 0;
}
这个示例中,我们创建了一个名为EventLoop
的类,它使用一个线程来运行事件循环。事件循环使用select
函数来监视多个套接字,当某个套接字准备好进行读/写操作时,相应的事件处理函数将被调用。在这个示例中,我们只处理了读和写事件,但在实际应用中,你可能需要处理更多类型的事件,例如连接建立、断开连接等。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。