| | |
| | | if (what & EVBUFFER_EOF)
|
| | | {
|
| | | //Client disconnected, remove the read event and the free the client structure.
|
| | | LOG_INFO << "Client disconnected.";
|
| | | LOG_INFO << "Client disconnected." << std::endl;
|
| | | }
|
| | | else
|
| | | {
|
| | | LOG_WARN << "Client socket error, disconnecting.";
|
| | | LOG_WARN << "Client socket error, disconnecting." << std::endl;
|
| | | }
|
| | | bufferevent_free(client->buf_ev);
|
| | | close(client->fd);
|
| | |
| | | // Write back the read buffer. It is important to note that
|
| | | // bufferevent_write_buffer will drain the incoming data so it
|
| | | // is effectively gone after we call it.
|
| | | //LOG_DEBUG << (char*)bufev->input;
|
| | | //LOG_DEBUG << (char*)bufev->input << std::endl;
|
| | | //bufferevent_write_buffer(bufev, bufev->input);
|
| | |
|
| | | //char buff[100] = {'\0'};
|
| | | //size_t readSize = bufferevent_read(bufev, buff, sizeof(buff));
|
| | | //LOG_DEBUG << "readSize=" << readSize << "\t" << buff;
|
| | | //LOG_DEBUG << "readSize=" << readSize << "\t" << buff << std::endl;
|
| | |
|
| | | EVPHeader* evpHeader = (EVPHeader*)client->recvbuff;
|
| | |
|
| | |
| | | client->read_times = 1;
|
| | | if (readSize != sizeof(headerBuff))
|
| | | {
|
| | | LOG_WARN << "client send incomplete header";
|
| | | LOG_WARN << "client send incomplete header" << std::endl;
|
| | | buffered_on_error(bufev, 0, arg);
|
| | | return;
|
| | | }
|
| | |
| | | if (evpHeader->cmd <= EVPCommand::EVPC__FIRST || evpHeader->cmd >= EVPCommand::EVPC__LAST ||
|
| | | evpHeader->size < sizeof(EVPHeader) || evpHeader->size > CLIENT_BUFFER_MAX)
|
| | | {
|
| | | LOG_WARN << "client send invalid header";
|
| | | LOG_WARN << "client send invalid header" << std::endl;
|
| | | buffered_on_error(bufev, 0, arg);
|
| | | return;
|
| | | }
|
| | |
| | | {
|
| | | size_t writeSize = bufferevent_write(bufev, cs.sendBuff, cs.sendBuffSize);
|
| | | if (writeSize != cs.sendBuffSize)
|
| | | LOG_WARN << "server send truncate " << (cs.sendBuffSize - writeSize) << " bytes";
|
| | | LOG_WARN << "server send truncate " << (cs.sendBuffSize - writeSize) << " bytes" << std::endl;
|
| | |
|
| | | if (cs.deleteSendBuff)
|
| | | delete[] cs.sendBuff;
|
| | |
| | |
|
| | | if (closeClient)
|
| | | {
|
| | | LOG_DEBUG << "server initiative close";
|
| | | LOG_DEBUG << "server initiative close" << std::endl;
|
| | | buffered_on_error(bufev, 0, arg);
|
| | | }
|
| | |
|
| | |
| | | // check read times
|
| | | if (client->read_times > CLIENT_READ_TIMES_MAX)
|
| | | {
|
| | | LOG_WARN << "client read times to max";
|
| | | LOG_WARN << "client read times to max" << std::endl;
|
| | | buffered_on_error(bufev, 0, arg);
|
| | | }
|
| | | }
|
| | |
| | | int client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
|
| | | if (client_fd < 0)
|
| | | {
|
| | | LOG_WARN << "accept failed";
|
| | | LOG_WARN << "accept failed" << std::endl;
|
| | | return;
|
| | | }
|
| | |
|
| | | // Set the client socket to non-blocking mode.
|
| | | if (setnonblock(client_fd) < 0)
|
| | | LOG_WARN << "failed to set client socket non-blocking";
|
| | | LOG_WARN << "failed to set client socket non-blocking" << std::endl;
|
| | |
|
| | | // We've accepted a new client, create a client object.
|
| | | struct EVClient* client = new EVClient;
|
| | | if (client == NULL)
|
| | | {
|
| | | LOG_ERROR << "malloc failed";
|
| | | LOG_ERROR << "malloc failed" << std::endl;
|
| | | }
|
| | | client->fd = client_fd;
|
| | | client->proc = evclient_proc;
|
| | |
| | | // We have to enable it before our callbacks will be called.
|
| | | bufferevent_enable(client->buf_ev, EV_READ);
|
| | |
|
| | | LOG_INFO << "Accepted connection from " << inet_ntoa(client_addr.sin_addr);
|
| | | LOG_INFO << "Accepted connection from " << inet_ntoa(client_addr.sin_addr) << std::endl;
|
| | | }
|
| | |
|
| | | int server_main(int argc, char **argv)
|
| | |
| | | int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
|
| | | if (listen_fd < 0)
|
| | | {
|
| | | LOG_ERROR << "create socket failed";
|
| | | LOG_ERROR << "create socket failed" << std::endl;
|
| | | return EXIT_FAILURE;
|
| | | }
|
| | |
|
| | |
| | | listen_addr.sin_port = htons(SERVER_PORT);
|
| | | if (bind(listen_fd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < 0)
|
| | | {
|
| | | LOG_ERROR << "bind failed";
|
| | | LOG_ERROR << "bind failed" << std::endl;
|
| | | return EXIT_FAILURE;
|
| | | }
|
| | |
|
| | | if (listen(listen_fd, 5) < 0)
|
| | | {
|
| | | LOG_ERROR << "listen failed";
|
| | | LOG_ERROR << "listen failed" << std::endl;
|
| | | return EXIT_FAILURE;
|
| | | }
|
| | |
|
| | |
| | | setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on));
|
| | | if (setnonblock(listen_fd) < 0)
|
| | | {
|
| | | LOG_ERROR << "failed to set server socket to non-blocking";
|
| | | LOG_ERROR << "failed to set server socket to non-blocking" << std::endl;
|
| | | return EXIT_FAILURE;
|
| | | }
|
| | |
|