├── Makefile.bsd ├── Makefile.linux ├── main.cpp ├── rbuffer.cpp ├── rbuffer.h ├── ss5.h ├── svr.cpp └── svr.h /Makefile.bsd: -------------------------------------------------------------------------------- 1 | CC=g++ 2 | CFLAGS=-c -DBSD=1 -ggdb3 -O0 -std=c++11 3 | LDFLAGS= 4 | LIBS= -lpthread 5 | SOURCES= main.cpp rbuffer.cpp svr.cpp 6 | OBJECTS=$(SOURCES:.cpp=.o) 7 | EXECUTABLE=ass5 8 | 9 | all: $(SOURCES) $(EXECUTABLE) 10 | 11 | $(EXECUTABLE): $(OBJECTS) 12 | $(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ 13 | 14 | .cpp.o: 15 | $(CC) $(CFLAGS) $< -o $@ 16 | 17 | clean: 18 | rm -rf $(OBJECTS) 19 | rm -rf $(EXECUTABLE) 20 | -------------------------------------------------------------------------------- /Makefile.linux: -------------------------------------------------------------------------------- 1 | CC=g++ 2 | CFLAGS=-c -DLINUX=1 -ggdb3 -O0 -std=c++11 3 | LDFLAGS= 4 | LIBS= -lpthread 5 | SOURCES= main.cpp rbuffer.cpp svr.cpp 6 | OBJECTS=$(SOURCES:.cpp=.o) 7 | EXECUTABLE=ass5 8 | 9 | all: $(SOURCES) $(EXECUTABLE) 10 | 11 | $(EXECUTABLE): $(OBJECTS) 12 | $(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ 13 | 14 | .cpp.o: 15 | $(CC) $(CFLAGS) $< -o $@ 16 | 17 | clean: 18 | rm -rf $(OBJECTS) 19 | rm -rf $(EXECUTABLE) 20 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sin5678/ass5/03047577e11805d77fe218d6309ac5625088f33f/main.cpp -------------------------------------------------------------------------------- /rbuffer.cpp: -------------------------------------------------------------------------------- 1 | //#include 2 | #include 3 | #include 4 | #include "rbuffer.h" 5 | 6 | 7 | #define RBUFFER_INIT_LEN 1024 8 | #define RBUFFER_INC_LEN 1024 9 | 10 | rbuffer::rbuffer() 11 | { 12 | begin = (unsigned char *) new char[RBUFFER_INIT_LEN]; 13 | end = begin + RBUFFER_INIT_LEN; 14 | head = begin; 15 | tail = head; 16 | } 17 | 18 | rbuffer::~rbuffer() 19 | { 20 | delete[] begin; 21 | begin = head = tail = end = NULL; 22 | } 23 | 24 | int rbuffer::getBufferLen() 25 | { 26 | int ret = 0; 27 | switch (getBufferType()) 28 | { 29 | case 0: 30 | break; 31 | case 1: 32 | { 33 | ret = tail - head; 34 | } 35 | break; 36 | case 2: 37 | { 38 | ret = tail - head; 39 | } 40 | break; 41 | case 3: 42 | { 43 | ret = end - head; 44 | } 45 | break; 46 | case 4: 47 | { 48 | ret = end - head + tail - begin; 49 | } 50 | break; 51 | case 5: 52 | { 53 | ret = end - head + tail - begin; 54 | } 55 | break; 56 | case 6: 57 | { 58 | ret = end - begin; 59 | } 60 | break; 61 | default: 62 | break; 63 | } 64 | return ret; 65 | } 66 | 67 | void rbuffer::copy(rbuffer * buff) 68 | { 69 | int len = getBufferLen(); 70 | unsigned char *p = (unsigned char *) new char[len]; 71 | read(p, len); 72 | write(p, len); 73 | buff->clearBuffer(); 74 | buff->write(p, len); 75 | } 76 | 77 | void rbuffer::write(void *data, int len) 78 | { 79 | RE_TRY: 80 | switch (getBufferType()) 81 | { 82 | case 0: 83 | { 84 | if (end - begin > len) 85 | { 86 | memcpy(head, data, len); 87 | tail += len; 88 | } 89 | else 90 | { 91 | delete[] begin; 92 | int newlen = RBUFFER_INIT_LEN + (size_t)(ceil((end - begin) / RBUFFER_INC_LEN) * RBUFFER_INC_LEN); 93 | begin = (unsigned char *) new char[newlen]; 94 | end = begin + newlen; 95 | head = tail = begin; 96 | goto RE_TRY; 97 | } 98 | } 99 | break; 100 | case 1: 101 | { 102 | if (end - tail > len) 103 | { 104 | memcpy(tail, data, len); 105 | tail += len; 106 | } 107 | else 108 | { 109 | int newlen = RBUFFER_INIT_LEN + (size_t)(ceil((end - begin + len) / RBUFFER_INC_LEN) * RBUFFER_INC_LEN); 110 | unsigned char *p = (unsigned char *) new char[newlen]; 111 | int datalen = tail - head; 112 | memcpy(p, begin, datalen); 113 | delete[] begin; 114 | begin = p; 115 | head = begin; 116 | tail = head + datalen; 117 | end = begin + newlen; 118 | goto RE_TRY; 119 | } 120 | } 121 | break; 122 | case 2: 123 | { 124 | if (end - tail > len) 125 | { 126 | memcpy(tail, data, len); 127 | tail += len; 128 | } 129 | else if ((end - tail + head - begin) > len) 130 | { 131 | memcpy(tail, data, end - tail); 132 | memcpy(begin, (unsigned char *)data + (size_t)end - (size_t)tail, len - (end - tail)); 133 | tail = begin + len - (end - tail); 134 | } 135 | else 136 | { 137 | int newlen = RBUFFER_INIT_LEN + (size_t)(ceil((end - begin + len) / RBUFFER_INC_LEN) * RBUFFER_INC_LEN); 138 | unsigned char *p = (unsigned char *) new char[newlen]; 139 | int datalen = tail - head; 140 | int headoff = (size_t)head - (size_t)begin; 141 | memcpy(p + headoff, head, datalen); 142 | delete[] begin; 143 | begin = p; 144 | head = begin + headoff; 145 | tail = head + datalen; 146 | end = begin + newlen; 147 | goto RE_TRY; 148 | } 149 | } 150 | break; 151 | case 3: 152 | { 153 | if (head - tail > len) 154 | { 155 | memcpy(begin, data, len); 156 | tail += len; 157 | } 158 | else 159 | { 160 | int newlen = RBUFFER_INIT_LEN + (size_t)(ceil((end - begin + len) / RBUFFER_INC_LEN) * RBUFFER_INC_LEN); 161 | unsigned char *p = (unsigned char *) new char[newlen]; 162 | int datalen = end - head; 163 | int headoff = (size_t)head - (size_t)begin; 164 | memcpy(p + headoff, head, datalen); 165 | delete[] begin; 166 | begin = p; 167 | head = begin + headoff; 168 | tail = head + datalen; 169 | end = begin + newlen; 170 | goto RE_TRY; 171 | } 172 | } 173 | break; 174 | case 4: 175 | { 176 | if (head - tail > len) 177 | { 178 | memcpy(tail, data, len); 179 | tail += len; 180 | } 181 | else 182 | { 183 | int newlen = (end - begin) * 2; 184 | unsigned char *p = (unsigned char *) new char[newlen]; 185 | int datalen = end - head + tail - begin; 186 | int headoff = (size_t)head - (size_t)begin; 187 | memcpy(p + headoff, head, end - head); 188 | memcpy(p + (size_t)end - (size_t)begin, begin, tail - begin); 189 | delete[] begin; 190 | begin = p; 191 | head = begin + headoff; 192 | tail = head + datalen; 193 | end = begin + newlen; 194 | goto RE_TRY; 195 | } 196 | } 197 | break; 198 | case 5: 199 | { 200 | int newlen = RBUFFER_INIT_LEN + (size_t)(ceil((end - begin + len) / RBUFFER_INC_LEN) * RBUFFER_INC_LEN); 201 | unsigned char *p = (unsigned char *) new char[newlen]; 202 | int datalen = end - head + tail - begin; 203 | int headoff = (size_t)head - (size_t)begin; 204 | memcpy(p + headoff, head, end - head); 205 | memcpy(p + (size_t)end - (size_t)begin, begin, tail - begin); 206 | delete[] begin; 207 | begin = p; 208 | head = begin + headoff; 209 | tail = head + datalen; 210 | end = begin + newlen; 211 | goto RE_TRY; 212 | } 213 | break; 214 | case 6: 215 | { 216 | int newlen = RBUFFER_INIT_LEN + (size_t)(ceil((end - begin) / RBUFFER_INC_LEN) * RBUFFER_INC_LEN); 217 | unsigned char *p = (unsigned char *) new char[newlen]; 218 | int datalen = end - begin; 219 | memcpy(p, begin, end - begin); 220 | delete[] begin; 221 | begin = p; 222 | end = begin + newlen; 223 | head = begin; 224 | tail = head + datalen; 225 | goto RE_TRY; 226 | } 227 | break; 228 | default: 229 | break; 230 | } 231 | } 232 | 233 | int rbuffer::read(void *data, int len) 234 | { 235 | int ret = 0; 236 | switch (getBufferType()) 237 | { 238 | case 0: 239 | { 240 | ret = 0; 241 | } 242 | break; 243 | case 1: 244 | { 245 | ret = ((tail - head) > len ? len : (tail - head)); 246 | if(data) memcpy(data, head, ret); 247 | head += ret; 248 | if (head == tail) 249 | head = tail = begin; 250 | } 251 | break; 252 | case 2: 253 | { 254 | ret = ((tail - head) > len ? len : (tail - head)); 255 | if(data) memcpy(data, head, ret); 256 | head += ret; 257 | if (head == tail) 258 | head = tail = begin; 259 | } 260 | break; 261 | case 3: 262 | { 263 | ret = ((end - head) > len ? len : (end - head)); 264 | if(data) memcpy(data, head, ret); 265 | head += ret; 266 | if (head == tail) 267 | head = tail = begin; 268 | } 269 | break; 270 | case 4: 271 | { 272 | int datalen = end - head + tail - begin; 273 | ret = (datalen > len ? len : datalen); 274 | if (ret <= end - head) 275 | { 276 | if(data) memcpy(data, head, ret); 277 | head += ret; 278 | } 279 | else 280 | { 281 | if(data) memcpy(data, head, end - head); 282 | if(data) memcpy((unsigned char *)data + (size_t)end - (size_t)head, begin, ret - (end - head)); 283 | head = begin + ret - (end - head); 284 | } 285 | if (head == tail) 286 | head = tail = begin; 287 | } 288 | break; 289 | case 5: 290 | { 291 | int datalen = end - head + tail - begin; 292 | ret = (datalen > len ? len : datalen); 293 | if (ret <= end - head) 294 | { 295 | if(data) memcpy(data, head, ret); 296 | head += ret; 297 | } 298 | else 299 | { 300 | if(data) memcpy(data, head, end - head); 301 | if(data) memcpy((unsigned char *)data + (size_t)end - (size_t)head, begin, ret - (end - head)); 302 | head = begin + ret - (end - head); 303 | } 304 | if (head == tail) 305 | head = tail = begin; 306 | } 307 | break; 308 | case 6: 309 | { 310 | ret = (end - begin > len ? len : (end - begin)); 311 | if(data) memcpy(data, begin, ret); 312 | head += ret; 313 | if (head == tail) 314 | head = tail = begin; 315 | } 316 | break; 317 | default: 318 | break; 319 | } 320 | return ret; 321 | } 322 | 323 | void rbuffer::clearBuffer() 324 | { 325 | head = begin; 326 | tail = head; 327 | } 328 | 329 | //private: 330 | int rbuffer::getBufferType() 331 | { 332 | if (head == tail && head == begin) return 0; 333 | if (tail == end && head == begin) return 6; 334 | if (tail == end) tail = begin; 335 | if (head == end) head = begin; 336 | if (head == begin && tail < end) return 1; 337 | if (head > begin && head < tail && tail < end) return 2; 338 | if (head > begin && head < end && tail == begin) return 3; 339 | if (head > begin && head < end && tail > begin && tail < head) return 4; 340 | if (head == tail && head < end && tail > begin) return 5; 341 | 342 | throw "unexcept ~!!\n"; 343 | } 344 | -------------------------------------------------------------------------------- /rbuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class rbuffer 3 | { 4 | public: 5 | rbuffer(); 6 | virtual ~rbuffer(); 7 | 8 | 9 | int getBufferLen(); 10 | void write(void *data, int len); 11 | int read(void *data, int len); 12 | void clearBuffer(); 13 | void copy(rbuffer *); 14 | private: 15 | int getBufferType(); 16 | private: 17 | unsigned char *begin; 18 | unsigned char *end; 19 | unsigned char *head; 20 | unsigned char *tail; 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /ss5.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sin5678/ass5/03047577e11805d77fe218d6309ac5625088f33f/ss5.h -------------------------------------------------------------------------------- /svr.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sin5678/ass5/03047577e11805d77fe218d6309ac5625088f33f/svr.cpp -------------------------------------------------------------------------------- /svr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "rbuffer.h" 7 | 8 | class SpinLock 9 | { 10 | public: 11 | void lock() 12 | { 13 | while (lck.test_and_set(std::memory_order_acquire)) 14 | { 15 | } 16 | } 17 | 18 | void unlock() 19 | { 20 | lck.clear(std::memory_order_release); 21 | } 22 | 23 | private: 24 | std::atomic_flag lck = ATOMIC_FLAG_INIT; 25 | }; 26 | 27 | 28 | #define dbg_msg printf 29 | 30 | struct ClientContext 31 | { 32 | int fd; 33 | in_addr host; 34 | int port; 35 | rbuffer buffer; 36 | int is_connect; 37 | void * lparam; 38 | }; 39 | 40 | enum MSG_TYPE 41 | { 42 | MSG_NEW_CLIENT, 43 | MSG_CONNECT_OK, 44 | MSG_RECV, 45 | MSG_CONNECT_ERROR, 46 | MSG_ERROR, 47 | MSG_DISCONNECT, 48 | }; 49 | 50 | typedef void(*on_msg)(ClientContext *, int msg); 51 | 52 | 53 | class svr 54 | { 55 | public: 56 | svr(); 57 | virtual ~svr(); 58 | public: 59 | bool start(int port, on_msg func); 60 | bool stop(); 61 | bool send(ClientContext *client, unsigned char *data, int len); 62 | ClientContext * connect(const char *host, int port); 63 | bool svrLoop(); 64 | void disconnect(ClientContext *); 65 | 66 | private: 67 | void onNewClient(ClientContext *); 68 | bool onAccept(); 69 | bool onRead(ClientContext *); 70 | bool onDisconnect(ClientContext *); 71 | bool onWrite(ClientContext *); 72 | bool onError(ClientContext *); 73 | void onHup(ClientContext *); 74 | bool AddFdOnWrite(int fd, void *data); 75 | bool AddFdOnRead(int fd, void *data); 76 | private: 77 | int m_svr_fd; 78 | #ifdef LINUX 79 | int m_epoll; 80 | #elif BSD 81 | int m_kq; 82 | #endif 83 | int m_stoping; 84 | int m_conn_pending; 85 | on_msg m_msg_func; 86 | std::list m_client_list; 87 | SpinLock m_lock; 88 | }; 89 | 90 | --------------------------------------------------------------------------------