Exemple #1
0
	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();
			}
		}
	}
Exemple #2
0
	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();
		}
	}
Exemple #5
0
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);
}