예제 #1
0
파일: EgSock.cpp 프로젝트: narychen/eg
int EgSock::Connect(const char* ip, uint16_t port, function<void(sp_EgSock)> callback) 
{
	_fd = CreateSocket();
	SetNonblock(fd);
	SetNodelay(fd);

	_peer_ip = ip;
	_port = port;
	_state = EG_SOCK_CONNECTING;
	_callback = callback;

	sockaddr_in serv_addr;
	SetAddr(ip, port,  &serv_addr);
	if (connect(_fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) {
		if (!((errno == EINPROGRESS) || (errno == EWOULDBLOCK))) {
			loge("connect failed, err_code=%d", errno);
			close(_fd);
			throw egex("connect failed, errno=%d", errno);
		}
	} else {
		_state = EG_SOCK_CONNECTED;
		callback(shared_from_this());
	}
	return _fd;
}
예제 #2
0
//生成套接字,并设置为非阻塞
bool Server::InitSockfd()
{
    log::log(Info,"init sock fd");
    if((m_sockfd = socket(AF_INET, SOCK_STREAM, 0))==-1)
    {
        return false;
    }
    //设置非阻塞

    return SetNonblock(m_sockfd);
}
예제 #3
0
파일: EgSock.cpp 프로젝트: narychen/eg
int EgSock::Listen(const char* ip, uint16_t port, function<void(sp_EgSock)> callback)
{
	_fd = CreateSocket();
	SetReuseAddr(_fd);
	SetNonblock(_fd);
	Bind(_fd, ip, port);

	if (listen(_fd, 64) == SOCKET_ERROR) {
		loge("listen failed, err_code=%d", errno);
		close(_fd);
		throw egex("listen failed, err_code=%d", errno);
	}

	_state = EG_SOCK_LISTENING;
	_callback = callback;
	return _fd;
}
예제 #4
0
파일: EgSock.cpp 프로젝트: narychen/eg
void EgSock::_OnAccept()
{
	int sessionFd = 0;
	sockaddr_in peer_addr;
	socklen_t addr_len = sizeof(sockaddr_in);
	char ip_str[64];
	while((sessionFd = accept(fd, (sockaddr*)&peer_addr, &addr_len)) != INVALID_SOCKET) {
		EgSock* sock = new EgSock();
		uint32_t ip = ntohl(peer_addr.sin_addr.s_addr);
		uint16_t port = ntohs(peer_addr.sin_port);
		snprintf(ip_str, sizeof(ip_str), "%d.%d.%d.%d", ip >> 24, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF);
		sock->SetPeerIp(ip_str);
		sock->SetPeerPort(port);
		sock->SetFd(sessionFd);
		sock->SetCallback(_callback);
		SetNodelay(sessionFd);
		SetNonblock(sessionFd);
		EgDispatch::Instance()->AddEvent(sessionFd);
	}
}
예제 #5
0
//服务器侦听套接字上的事件
void Server::OnRead()
{
    log::log(Info,"handle accept evets!");
    //建立新的连接
    struct sockaddr_in addr;
    socklen_t len = sizeof(sockaddr);
    int sockfd = accept(m_sockfd,(sockaddr *)&addr,&len);
           
    if(sockfd<0)
    {
        log::log(Error,"connfd < 0");
        return;
    }
    //设置为非阻塞
    SetNonblock(sockfd);
   
    //创建连接
    Connection* conn = new Connection(sockfd,addr,this);
 
    std::map<uint64_t, Connection*>::iterator it = m_connections.find(sockfd);
    if(it != m_connections.end())
    {
        Connection* connection =it->second;
        //这个连接已经存在,其实是不可能的,但是还是删除把
        m_selector->Remove(connection);
        m_connections.erase(it);
        delete connection;
    }
    //插入m_connections中,以IP为键,这样不合理,同一个IP会登陆多个客户端,所以还是用套接字作为键吧
    m_connections[sockfd] = conn;

    //打印一些信息
    log::log(Info,"m_connections.size() = ",m_connections.size());
    char *str = inet_ntoa(addr.sin_addr);
    unsigned short port = ntohs(addr.sin_port);
    log::log(Info,"accept a connection from ip:",str,"port",port);

    //添加到epoll中
    m_selector->Select(conn,0,0);
    log::log(Info,"m_selector.size:",m_selector->Size());
}
예제 #6
0
BOOL CTcpEpollServer::EpollAcceptSocket(SOCKET hSocket, const sockaddr_in& SockAddr)
{
	if(INVALID_SOCKET == hSocket)
		return FALSE;

    // 设置程非阻塞式SOCKET
    if (!SetNonblock(hSocket, TRUE))
    {
        return FALSE;
    }

	// 回调上层创建context
	CTcpContext *pContext = CreateContext();
	if (pContext == NULL)
	{
		return FALSE;
	}

	// Context 赋值
	pContext->m_hSocket = hSocket;
	memcpy(&pContext->m_oSocketAddr, &SockAddr, sizeof(sockaddr_in));

	// 添加至队列
	AddTcpContext(pContext);

	struct epoll_event ev;
	ev.events	= EPOLLIN | EPOLLOUT | EPOLLET;  //ET模式+读事件+写事件
	ev.data.ptr = (void*)pContext;
	if (epoll_ctl(m_hEpollHandle, EPOLL_CTL_ADD, hSocket, &ev) < 0)
	{
		RemoveTcpContext(pContext);
		DestroyContext(pContext);
		return FALSE;
	}

	return TRUE;
}
예제 #7
0
//生成套接字,并设置为非阻塞
void Client::InitSockfd(int& sockfd)
{
    sockfd = socket(AF_INET, SOCK_STREAM, 0);//tcp
    //设置非阻塞
    SetNonblock(sockfd);
}
예제 #8
0
/// 创建SOCKET套接字
SOCKET CTcpEpollServer::CreateSocket(uint16_t nSvrPort)
{
	SOCKET hSocket = INVALID_SOCKET;

	BOOL bIsSucceed = FALSE;
	do
	{
		// 创建监听Socket
		SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
		if (hSocket == INVALID_SOCKET)
		{
			TraceLogError("CTcpEpollServer::CreateSocket 创建SOCKET失败 ERROR=%s!\n",
				strerror(errno));
			break;
		}

		//设置Socket绑定的服务器IP地址、端口可以重用。
		//防止服务器在发生意外时,端口未被释放,造成无法启动;设置后可以重新使用了。
		unsigned int optval = 0x1;
		setsockopt(hSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(unsigned int));

		//设置程非阻塞式SOCKET
		if (!SetNonblock(hSocket,TRUE))
		{
			TraceLogError("CTcpEpollServer::CreateSocket SetNonblock失败 SOCKET=%d!\n",
				hSocket);
			break;
		}

		//绑定端口
		sockaddr_in  addr;
		memset(&addr,0,sizeof(sockaddr_in));
		addr.sin_family = AF_INET;
		addr.sin_addr.s_addr = INADDR_ANY;
		addr.sin_port = htons(nSvrPort);
		if (SOCKET_ERROR == bind(hSocket,(sockaddr *)&addr, sizeof(sockaddr_in)))
		{
			TraceLogError("CTcpEpollServer::CreateSocket 绑定端口失败 PORT=%d ERROR=%s!\n",
				nSvrPort, strerror(errno));
			break;
		}

		//开始侦听
		if (listen(hSocket, 100) == SOCKET_ERROR)
		{
			TraceLogError("CTcpEpollServer::CreateSocket 监听失败 ERROR=%s!\n",
				strerror(errno));
			break;
		}

		bIsSucceed = TRUE;
	} while (FALSE);

	if(!bIsSucceed)
	{
		if(INVALID_SOCKET != hSocket)
		{
			close(hSocket);
			hSocket = INVALID_SOCKET;
		}
	}
	return hSocket;
}