/* * 监听 */ 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; }
/* * 处理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; }
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; } }
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; }
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; }