-
Notifications
You must be signed in to change notification settings - Fork 0
/
MiniServer.cpp
96 lines (87 loc) · 2.98 KB
/
MiniServer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <semaphore.h>
#include <signal.h>
#include <algorithm>
#include "MiniLog.hpp"
#include "ReactorThread.hpp"
static sem_t *sem = new sem_t;
static void signal_handler(int sig_num)
{
//signal(SIGINT, signal_handler);
printf("exit\n");
sem_post(sem);
}
void onRead(SpChannel chan)
{
int fd = chan->GetSocket();
SpReactor re = std::static_pointer_cast<Reactor>(chan->GetSpPrivData());
char recvBuffer[1024] = {};
int ret = recv(fd, recvBuffer, sizeof(recvBuffer), 0);
if (ret == 0) {
minilog(LogLevel_e::WARRNIG, "peer close");
re->DelChannel(chan);
}
else if (ret < 0) {
minilog(LogLevel_e::DEBUG, "onRead ret < 0 errno = %d", errno);
if(!(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)){
minilog(LogLevel_e::ERROR, strerror(errno));
re->DelChannel(chan);
}
}
else{
minilog(LogLevel_e::DEBUG, "onRead ret = %d", ret);
chan->GetSendBuffer().clear();
chan->AppendSendBuffer(std::string(recvBuffer));
std::transform(chan->GetSendBuffer().begin(), chan->GetSendBuffer().end(), chan->GetSendBuffer().begin(), ::toupper);
re->EnableEvents(chan, ChannelEvent_e::OUT);
}
return;
}
void onSend(SpChannel chan)
{
SpReactor re = std::static_pointer_cast<Reactor>(chan->GetSpPrivData());
if (!chan->GetSendBuffer().empty()) {
auto sendLen = send(chan->GetSocket(), chan->GetSendBuffer().c_str(), chan->GetSendBuffer().size(), 0);
minilog(LogLevel_e::DEBUG, "onSend sendLen = %d", sendLen);
if (sendLen > 0) {
chan->GetSendBuffer() = chan->GetSendBuffer().substr(sendLen);
}
}
if (chan->GetSendBuffer().empty()) {
re->DisableEvents(chan, ChannelEvent_e::OUT);
}
return;
}
void onConnect(SpChannel chan)
{
SpReactor re = std::static_pointer_cast<Reactor>(chan->GetSpPrivData());
int fd = chan->GetSocket();
sockaddr_in clientAddr = {};
socklen_t len = sizeof(clientAddr);
int clientFd = accept(fd, (sockaddr*)&clientAddr, &len);
minilog(LogLevel_e::INFO, "accept client address : %s:%d", inet_ntoa(clientAddr.sin_addr), htons(clientAddr.sin_port));
if (clientFd == -1) {
if (errno != EAGAIN && errno != EINTR) {
return;
}
minilog(LogLevel_e::ERROR, "accept error:%s", strerror(errno));
}
else {
fcntl(clientFd, F_SETFL, O_NONBLOCK);
re->AddChannel(CreateSpChannel(clientFd, re, onRead, onSend, nullptr), ChannelEvent_e::IN);
}
}
int main()
{
sem_init(sem, 0, 0);
signal(SIGINT, signal_handler);
SpReactorThread mainRe = CreateSpReactorThread("main_reactor");
mainRe->Open();
SpReactorThread subRe = CreateSpReactorThread("sub_reactor");
subRe->Open();
mainRe->Reactor()->AddChannel(CreateSpChannelListen(12222, subRe->Reactor(), onConnect, nullptr), ChannelEvent_e::IN);
sem_wait(sem);
//listenThrd.Stop();
//subThrd.Stop();
printf("main end\n");
return 0;
}