Пример #1
0
/*
 * 监听
 */
int TCPServer_Listen(TCPServer* pServer)
{
	// 1、设置非阻塞
	int iRet = socketapi_setnonblocking(pServer->iServSocket, 1);
	if(iRet < 0)
	{
		XLOG_ERROR(pServer->pLogger, "SetNoBlock() fail.");
		socketapi_close(pServer->iServSocket);
		return -2;
	}

	// 3、设置地址复用
	iRet = socketapi_setreuse(pServer->iServSocket, 1);
	if(iRet == -1)
	{
		XLOG_ERROR(pServer->pLogger, "SetReuseAddr() fail.");
		socketapi_close(pServer->iServSocket);
		return -3;
	}

	// 5、bind()绑定
	sockaddr_in stServAddr;
	memset(&stServAddr, 0, sizeof(stServAddr));
	stServAddr.sa_family = AF_INET;
	stServAddr.sin_port = htons(pServer->dwPort);
	stServAddr.sin_addr.s_addr = inet_addr(pServer->szIP);
	
	int iSize = sizeof(stServAddr);
	iRet = socketapi_bind(pServer->iServSocket, &stServAddr, iSize);
	if(iRet == -1)
	{
		XLOG_ERROR(pServer->pLogger, "Bind() fail: error:%s", strerror(errno));
		socketapi_close(pServer->iServSocket);
		return -4;
	}

	// 6、listen
	iRet = socketapi_listen(pServer->iServSocket, pServer->iBacklog);
	if(iRet == -1)
	{
		XLOG_ERROR(pServer->pLogger, "Listen() fail:iRet=%d,error:%s", iRet, strerror(errno));
		socketapi_close(pServer->iServSocket);
		return -5;
	}

	// 8、EventAdd相应读事件
	iRet = Epoller_EventAdd(pServer->iServSocket, EVENT_READ|EVENT_ERROR);
	if(iRet < 0)
	{
		XLOG_ERROR(pServer->pLogger, "EventAdd failed!");
		socketapi_close(pServer->iServSocket);
		return -6;
	}

	return 0;
}
Пример #2
0
/*
 * 处理Accept
 */
int TCPServer_Accept(TCPServer* pServer)
{
	if(pServer == NULL)
	{
		return -1;
	}

	// step 1: accept接收新连接
	sockaddr_in stAddr;
	memset(&stAddr, 0, sizeof(stAddr));
	int iLen = sizeof(stAddr);
	int iSock = socketapi_accept(pServer->iServSocket, (struct sockaddr*)&stAddr, (socklen_t*)&iLen);
	if(iSock == -1)
	{
		if(errno == EAGAIN || errno == EINTR)
		{
			return 0;
		}

		XLOG_ERROR(pServer->pLogger, "[error] accept error: (%s).", strerror(errno));
		return -2;
	}

	// step 2: 置为非阻塞
	int iRet = socketapi_setnonblocking(iSock, 1);
	if(iRet < 0)
	{
		XLOG_ERROR(pServer->pLogger, "SetNonBlocking() fail: %d", iRet);
		return -3;
	}

	// step 3: 添加事件
	iRet = Epoller_EventAdd(pServer->pEpoller, iSock, EVENT_READ | EVENT_ERROR);
	if(iRet < 0)
	{
		XLOG_ERROR(pServer->pLogger, "EventAdd() fail: %d", iRet);
		socketapi_close(iSock);
		return -4;
	}

	// 额外工作,留出API (不退出程序)
#if 0
	iRet = OnAccept(iSock);
	if(iRet < 0)
	{
		XLOG_ERROR(m_pLogger, "OnAccept() fail: %d", iRet);
	}
#endif

	return 0;
}
Пример #3
0
int TCPServer_CloseConnection(SOCKET iSocket)
{
	if(iSocket <= 0)
	{
		return -1;
	}

	int iRet = socketapi_close(iSocket);
	if(iRet < 0)
	{
		XLOG_ERROR(m_pLogger, "Close() failed!");
		return -2;
	}

	// 2、删除epoll
	iRet = Epoller_EventDel(pEpoller, iSocket);
	if(iRet < 0)
	{
		XLOG_ERROR(m_pLogger, "EventDel failed!");
		return -3;
	}
}
Пример #4
0
tlibc_error_code_t socketapi_send(socketapi_t *self, char *packet, uint16_t packet_len)
{
	tlibc_error_code_t ret = E_TLIBC_NOERROR;
	struct iovec iov[1];
	ssize_t send_size;

	if(self->socket_fd == -1)
	{
		if(!socketapi_open(self))
		{
			ret = E_TLIBC_ERRNO;
			goto done;
		}
	}
	iov[0].iov_base = (char*)packet;
	iov[0].iov_len = packet_len;
	
	//可以加入缓存降低系统调用次数。
    send_size = writev(self->socket_fd, iov, 1);
	if(send_size != iov[0].iov_len)
	{
		ret = E_TLIBC_ERRNO;
		if((errno == EAGAIN) || (errno == EINTR))
		{
			goto done;
		}
		else
		{
			socketapi_close(self);
			goto done;
		}
	}

done:
	return ret;
}
Пример #5
0
tlibc_error_code_t socketapi_process(socketapi_t *self)
{
	char *iter, *last, *limit;
	tlibc_error_code_t ret = E_TLIBC_NOERROR;
	ssize_t recv_size;
	if(self->socket_fd == -1)
	{
		ret = E_TLIBC_WOULD_BLOCK;
		goto done;
	}

	recv_size = recv(self->socket_fd, self->recvbuf + self->recvbuf_size, (size_t)(SOCKETAPI_RECVBUF_SIZE - self->recvbuf_size), 0);
	if(recv_size < 0)
	{
		if(errno == EAGAIN)
		{
			ret = E_TLIBC_WOULD_BLOCK;
			goto done;
		}
		else if(errno == EINTR)
		{
			goto done;
		}
		else
		{
			socketapi_close(self);
			goto done;
		}
	}

	self->recvbuf_size += (size_t)recv_size;



	last = NULL;
	limit = self->recvbuf + self->recvbuf_size;
	for(iter = self->recvbuf; iter <= limit;)
	{
		char *next;
		uint16_t packet_size;
		char* packet;
		if(limit - iter < sizeof(uint16_t))
		{
			break;
		}

		packet_size = *(uint16_t*)iter;
#ifdef TSF4G_BIGENDIAN
		packet_size = be16toh(packet_size);
#endif//TSF4G_BIGENDIAN
		packet = iter + sizeof(uint16_t);
		next = packet + packet_size;
		if(next <= limit)
		{
			last = next;
			if(self->on_recv)
			{
				self->on_recv(self, packet, packet_size);
			}
		}
		iter = next;
	}

	if((last) && (last < limit))
	{
		self->recvbuf_size = (size_t)(limit - last);
		memcpy(self->recvbuf, last, self->recvbuf_size);
	}

done:
	return ret;
}