#include <cstdio>
#include <event2/event.h>
#include <event2/listener.h>
#include <arpa/inet.h>
#include <event2/bufferevent.h>
#include <unistd.h>
#include <list>
#include <iostream>
std::list<struct bufferevent*> buffd_list;
void ReadEventCallback(struct bufferevent* bev, void* ctx)
{
std::cout << "Call Read Event Callback funcation" << std::endl;
char buf[1024];
int len = bufferevent_read(bev, buf, sizeof(buf));
int i = 0;
for (auto& buflist : buffd_list){
if (buflist != bev){
bufferevent_write(buflist, buf, len);
i++;
std::cout << "send data: " << buf << " send number: " << i << std::endl;
}
}
}
void WriteEventCallback(struct bufferevent* bev, void* ctx)
{
printf("写事件回调函数被调用");
}
void EventsCallback(struct bufferevent* bev, short events, void* ctx)
{
if (events & BEV_EVENT_ERROR)
{
printf("发生了某些错误...\n");
}
else if (events & BEV_EVENT_EOF)
{
printf("客户端断开了连接...\n");
bufferevent_free(bev);
}
}
void ListenerCallBack(struct evconnlistener* listener,
evutil_socket_t sock,
struct sockaddr* addr,
int len,void* ptr)
{
struct event_base* base = (struct event_base*)ptr;
struct bufferevent* bev = bufferevent_socket_new(base, sock, BEV_OPT_CLOSE_ON_FREE);
buffd_list.push_back(bev);
bufferevent_setcb(bev, ReadEventCallback, WriteEventCallback, EventsCallback, NULL);
bufferevent_enable(bev, EV_READ);
std::cout << "push back one sock" << std::endl;
}
int main()
{
struct event_base* Event_Fream = event_base_new();
std::cout << "build event fream" << std::endl;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9999);
addr.sin_addr.s_addr = INADDR_ANY;
struct evconnlistener* Listener;
Listener = evconnlistener_new_bind(Event_Fream, ListenerCallBack, Event_Fream,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
-1, (struct sockaddr*)&addr, sizeof(addr));
std::cout << "start listen port: " << addr.sin_port;
event_base_dispatch(Event_Fream);
std::cout << "start event loop" << std::endl;
evconnlistener_free(Listener);
event_base_free(Event_Fream);
return 0;
}
#pragma once
#include <sys/socket.h>
#include <arpa/inet.h>
#include <iostream>
#include <unistd.h>
#include <list>
#include <sys/epoll.h>
class tcp_server
{
public:
bool server_listen();
void server_run();
void server_close();
static tcp_server* getinstance();
private:
struct sockaddr_in addr;
int listen_fd;
int connect_fd;
std::list<int> accept_list;
struct epoll_event epr[100];
int epoll_tree;
int epoll_count;
tcp_server();
tcp_server(const tcp_server&);
static tcp_server* server_ptr;
};
#include "tcp_server.h"
tcp_server* tcp_server::server_ptr = NULL;
tcp_server::tcp_server()
{}
tcp_server::tcp_server(const tcp_server&)
{}
bool tcp_server::server_listen()
{
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror("socket");
return false;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(8851);
int ret = bind(listen_fd,(struct sockaddr*)&addr,sizeof(addr));
if (ret < 0) {
perror("bind");
return false;
}
ret = listen(listen_fd,128);
if (ret < 0) {
perror("listen");
return false;
}
epoll_tree = epoll_create(1);
struct epoll_event evt;
evt.data.fd = listen_fd;
evt.events = EPOLLIN;
ret = epoll_ctl(epoll_tree, EPOLL_CTL_ADD, listen_fd, &evt);
if (ret == -1)
{
perror("epoll_ctl");
std::cout << "listen fd:" << listen_fd << std::endl;
std::cout << "epoll_tree fd:" << epoll_tree << std::endl;
return false;
}
std::cout << "established listen and create epoll tree" << std::endl;
return true;
}
void tcp_server::server_run()
{
if (!server_listen())
{
std::cout << "server listen error" << std::endl;
server_close();
return;
}
int size = sizeof(epr) / sizeof(epoll_event);
std::cout << "main server loop start" << std::endl;
while(1) {
epoll_count = epoll_wait(epoll_tree, epr, size, -1);
for (int i = 0; i < epoll_count; i++) {
if (epr[i].data.fd == listen_fd) {
int cfd = accept(listen_fd, NULL, NULL);
if (cfd < 0){
perror("accept");
continue;
}
epoll_event evt;
evt.data.fd = cfd;
evt.events = EPOLLIN;
int ret = epoll_ctl(epoll_tree, EPOLL_CTL_ADD, cfd, &evt);
if (ret == -1)
{
perror("epoll_ctl");
return ;
}
accept_list.push_back(cfd);
std::cout << "Add a link file" << std::endl;
}
else{
char buf[100] = { 0 };
int count = recv(epr[i].data.fd, buf, sizeof(buf), 0);
if (count <= 0 ){
perror("recv");
continue;
}
for (auto it : accept_list){
if (it != epr[i].data.fd){
send(it, buf, count, 0);
std::cout << "send data: " << buf << " file describes: " << it << std::endl;
}
}
}
}
}
}
void tcp_server::server_close()
{
for (auto it : accept_list){
close(it);
}
close(listen_fd);
close(epoll_tree);
}
tcp_server* tcp_server::getinstance()
{
if (server_ptr != nullptr){
return server_ptr;
}
server_ptr = new tcp_server;
return server_ptr;
}
#include <cstdio>
#include "tcp_server.h"
int main()
{
tcp_server* tcp = tcp_server::getinstance();
tcp->server_run();
return 0;
}