void TcpServerReceiveThread::Main() { SocketThreadOperation *op = mSocketThreadOperation; TcpServerSocket *s = (TcpServerSocket*)op->mSocket; ErrorType error; StopWatch sw; sw.Start(); while (!ShouldEnd()) { error = s->Receive(op->mTcpClientConnectionID, &op->mByteStream, Math::ClampLong( op->mTimeoutMS - sw.GetElapsedMilliseconds(), 0L, 33L)); if (0L == op->mTimeoutMS || (error && kErrorTimedOut != error) || (0L < op->mTimeoutMS && sw.GetElapsedMilliseconds() >= op->mTimeoutMS)) { if (error) Error::Throw(error, String("[%s(%p, %p)]", FastFunctionName, this, op)); s->OnReceive(op->mID, op->mTcpClientConnectionID, op->mByteStream, error); sw.Reset(); sw.Start(); } } }
void TcpServerListenThread::Main() { SocketThreadOperation *op = mSocketThreadOperation; TcpServerSocket *s = (TcpServerSocket*)op->mSocket; ErrorType error; TcpClientConnection tcc; StopWatch sw; sw.Start(); while (!ShouldEnd()) { error = s->GetIncomingConnection(&tcc, Math::ClampLong( op->mTimeoutMS - sw.GetElapsedMilliseconds(), 0L, 33L)); if (0L == op->mTimeoutMS || (error && kErrorTimedOut != error) || (0L < op->mTimeoutMS && sw.GetElapsedMilliseconds() >= op->mTimeoutMS)) { if (error) Error::Throw(error, String("[%s(%p, %p)]", FastFunctionName, this, op)); s->OnClientConnect(op->mID, TcpClientConnection(), kErrorTimedOut); } } }
static typename T::VALUE_TYPE Execute(const typename T::VALUE_TYPE& value) { TcpServerSocket serverSocket; serverSocket.bind(0); serverSocket.listen(10); TestTcpSenderRunnable<T> testSender(value, serverSocket.port()); Thread thread; thread.start(testSender); TcpSocket* socket = serverSocket.accept(); TcpSocketInputStream inStream(*socket); typename T::VALUE_TYPE resultValue; inStream >> resultValue; thread.join(); delete socket; serverSocket.close(); return resultValue; }
void stopServer() { if (tss != DeletedObject) { tss->close(); } }
void* TcpServerSocket::_runListening(void *obj) { TcpServerSocket *p = (TcpServerSocket*) obj;//当前TcpServerSocket对象指针 p->running = true; //监视状态发生变化的socket struct epoll_event ev;//设置监听的读写事件 struct epoll_event events[MAX_EPOLL_FD_NUM];//监听到的读写事件数组 int num_fd_change;//状态发生变化的fd数量 int client_socket; struct sockaddr_in client_addr;//客户端地址结构 socklen_t client_addrlen = sizeof(struct sockaddr_in);//地址结构长度 int bytes;//数据字节数 char data[MAX_BUF_SIZE];//存储数据 while (p->running) { //等待直到有事件发生 //返回值为发生事件的socket数量 num_fd_change = epoll_wait(p->epollfd, events, MAX_EPOLL_FD_NUM, -1); //遍历每个状态改变的socket for (int n = 0; n < num_fd_change; ++n) { //如果该socket是服务socket,则证明accept到新连接 if (events[n].data.fd == p->server_socket) { memset(&client_addr, 0, sizeof(client_addr)); client_socket = accept(p->server_socket, (struct sockaddr*)&client_addr, &client_addrlen); //无效套接字 if (client_socket < 0) { continue; } p->setnonblocking(client_socket); // 将新连接置于非阻塞模式 //对新连接进行处理 //p->accept_handler(client_socket,client_addr); //在日志中记录客户端ip地址和端口号 string format = "服务器收到新的TCP连接请求 访问来自 %s:%u"; char message[256]; snprintf(message, 256, format.c_str(), inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); Manager::log.record(string(message)); // 并且将新连接也加入EPOLL的监听队列 ev.events = EPOLLIN | EPOLLOUT | EPOLLHUP| EPOLLRDHUP | EPOLLERR | EPOLLET; ev.data.fd = client_socket; if(epoll_ctl(p->epollfd, EPOLL_CTL_ADD, client_socket, &ev) < 0) { string format = "epoll注册监听错误: listen socket = %d\n"; char message[50]; snprintf(message, 50, format.c_str(), client_socket); Manager::log.record(message); continue; } } //如果是已经连接的用户,并且收到数据,那么进行读入 else if (events[n].events & EPOLLIN) { int sockfd_r; //可读socket //socket无效 if ((sockfd_r = events[n].data.fd) < 0) { p->tcp_except(sockfd_r); continue; } bytes = read(sockfd_r, data, MAX_BUF_SIZE); //对接收到的数据进行处理 if (bytes > 0) { p->recv_handler(sockfd_r, data); } else if (bytes == 0) { if (errno != EAGAIN && errno != EINTR) { string err = "else if (bytes == 0) errno=" + errno + string(strerror(errno)); Manager::log.record(err); //对无效套接字进行处理或者如果是连接用户断开连接 p->tcp_except(sockfd_r); } } //移除异常断开的连接 else if (bytes == -1) { if (errno != EAGAIN && errno != EINTR) { string err = "else if (bytes == -1) errno=" + errno + string(strerror(errno)); Manager::log.record(err); //对无效套接字进行处理或者如果是连接用户断开连接 p->tcp_except(sockfd_r); } } } //有可能捕获得到客户端连接已经断开 else if (events[n].events & EPOLLHUP) { string err = "else if (events[n].events & EPOLLHUP) errno=" + errno + string(strerror(errno)); Manager::log.record(err); int sockfd_h = events[n].data.fd; p->tcp_except(sockfd_h); } //有可能捕获得到客户端连接已经断开 else if (events[n].events & EPOLLRDHUP) { string err = "else if (events[n].events & EPOLLRDHUP) errno=" + errno + string(strerror(errno)); Manager::log.record(err); int sockfd_h = events[n].data.fd; p->tcp_except(sockfd_h); } //操作连接出错 else if (events[n].events & EPOLLERR) { if (errno != EAGAIN && errno != EINTR) { string err = "else if (events[n].events & EPOLLERR) errno=" + errno + string(strerror(errno)); Manager::log.record(err); //对错误套接字进行处理 int sockfd_e = events[n].data.fd; p->tcp_except(sockfd_e); } } } } return ((void*)0); }