ProtocolEvent SocketWrapper::openConnection( const struct sockaddr *saddr, socklen_t addrlen) { bool wasNonBlock = isNonblock(); if (INVALID_SOCKET == sock) { HAGGLE_ERR("Socket is invalid\n"); return PROT_EVENT_ERROR; } if (!saddr) { HAGGLE_ERR("Address is invalid\n"); return PROT_EVENT_ERROR; } // block while connecting if (nonblock) { setNonblock(false); } bool hasError = false; int ret = ::connect(sock, saddr, addrlen); if (SOCKET_ERROR == ret) { hasError = true; HAGGLE_ERR("Problems connecting: %s\n", SocketWrapper::getProtocolErrorStr()); } if (wasNonBlock) { setNonblock(true); } if (!hasError) { HAGGLE_DBG("Succesfully connected to socket.\n"); setConnected(true); return PROT_EVENT_SUCCESS; } else { HAGGLE_DBG("An error occurred connecting: %s\n", getProtocolErrorStr()); } switch (getProtocolError()) { case PROT_ERROR_BAD_HANDLE: case PROT_ERROR_INVALID_ARGUMENT: case PROT_ERROR_NO_MEMORY: case PROT_ERROR_NOT_A_SOCKET: case PROT_ERROR_NO_STORAGE_SPACE: return PROT_EVENT_ERROR_FATAL; default: return PROT_EVENT_ERROR; } }
bool ExternalSource::prepare() { if (!mMonitor.init() || !setNonblock(mMveStartupUds.getFd()) || !mMonitor.add(mMveStartupUds.getFd()) || !setNonblock(mMaliStartupUds.getFd()) || !mMonitor.add(mMaliStartupUds.getFd()) || !setNonblock(mAnnotate.getFd()) || !mMonitor.add(mAnnotate.getFd()) || false) { return false; } connectMali(); connectMve(); return true; }
ThreadPoolDispatcher::ThreadPoolDispatcher( Epoll *pEpoll, ThreadPool *pPool) : m_pEpoll(pEpoll), m_pThreadPool(pPool) { assert(pEpoll); assert(pPool); // set state m_iConnect = CONNECTED; // init EpollEvent m_ReadEpollEvent.setEpoll(m_pEpoll); m_WriteEpollEvent.setEpoll(m_pEpoll); m_ReadEpollEvent.setHandler(this); m_WriteEpollEvent.setHandler(this); // get thread pool handle m_hThreadPoolHandle = m_pThreadPool->getHandle(); setNonblock(m_hThreadPoolHandle); // 设置线程池句柄 m_WriteEpollEvent.setFd(m_hThreadPoolHandle); m_WriteEpollEvent.registerWEvent(); // 关闭写事件 m_WriteEpollEvent.closeWevent(); // init pipe int fd[2]; int rt = pipe(fd); if (0 != rt) { ERROR_LOG("Syscall Error: pipe. %s", strerror(errno)); } m_hReadHandle = fd[0]; m_hWriteHandle = fd[1]; setNonblock(m_hReadHandle); m_ReadEpollEvent.setFd(m_hReadHandle); // 注册管道读事件 m_ReadEpollEvent.registerREvent(); }
Socket::Socket(const SWORD sock,const struct sockaddr_in *addr,const bool compress) { m_bitMask = 0; assert(sock != -1); this->m_sock = sock; m_sockChange = 0; m_kdpfd = 0; bzero(&this->m_addr,sizeof(struct sockaddr_in)); if(!addr) { socklen_t len = sizeof(struct sockaddr); getpeername(this->m_sock,(struct sockaddr*)&this->m_addr,&len); } else { bcopy(addr,&this->m_addr,sizeof(struct sockaddr_in)); } bzero(&m_localAddr,sizeof(struct sockaddr_in)); socklen_t len = sizeof(struct sockaddr_in); getsockname(this->m_sock,(struct sockaddr *)&m_localAddr,&len); //设置当生成子进程时,子进程对应的套接口强制关闭 fcntl(this->m_sock,F_SETFD,fcntl(this->m_sock,F_GETFD,0) | FD_CLOEXEC); setNonblock(); m_rdMsec = s_rdMsec; m_wrMsec = s_wrMsec; m_recvRawSize = 0; m_currentCmd = 0; setFlag(s_incompleteRead | s_incompleteWrite); #if 0 if(compress) { m_bitMask |= s_packetZip; } #endif }
bool SocketWrapper::openSocket( int domain, int type, int protocol, bool registersock, bool nonblock) { if (INVALID_SOCKET != sock) { HAGGLE_ERR("socket already open\n"); return false; } sock = ::socket(domain, type, protocol); if (INVALID_SOCKET == sock) { HAGGLE_ERR("could not open socket\n"); return false; } if (!setNonblock(nonblock)) { closeSocket(); return false; } if (registersock && !registerSocket()) { closeSocket(); return false; } return true; }
void accept_callback(SOCK s,void *ud) { ENGINE *engine = (ENGINE*)ud; struct connection *c = connection_create(s,0,SINGLE_THREAD,on_process_packet,remove_client); add_client(c); setNonblock(s); connection_start_recv(c); Bind2Engine(*engine,s,RecvFinish,SendFinish,NULL); }
void accept_callback(HANDLE s,void *ud) { HANDLE *engine = (HANDLE*)ud; struct connection *c = connection_create(s,0,SINGLE_THREAD,on_process_packet,remove_client); printf("cli fd:%d\n",s); setNonblock(s); //·¢³öµÚÒ»¸ö¶ÁÇëÇó connection_start_recv(c); Bind2Engine(*engine,s,RecvFinish,SendFinish); }
void accept_callback(HANDLE s,void *ud) { HANDLE *engine = (HANDLE*)ud; struct connection *c = connection_create(s,0,0,on_process_packet,remove_client); add_client(c); printf("cli fd:%d\n",s); setNonblock(s); //发出第一个读请求 connection_start_recv(c); Bind2Engine(*engine,s,RecvFinish,SendFinish); }
/* ==================== acppet a new client fd ==================== */ void acceptNewClient (SOCKET listenfd) { SOCKET newDesc; struct sockaddr_in peer; #if defined (WIN32) int peersize; #else socklen_t peersize; #endif peersize = sizeof (peer); newDesc = accept (listenfd, (struct sockaddr*) &peer, &peersize); if (newDesc < 0) { outLog ((char*)"accept new client failed!\r\n"); return; } setNonblock (newDesc); struct sPacket* newClient = (struct sPacket*) malloc (sizeof (struct sPacket*)); if (!newClient) { CLOSESOCKET (newDesc); return; } newClient->m_sock = newDesc; (void*) strcpy (newClient->m_ip, (char*) inet_ntoa (peer.sin_addr)); *newClient->m_recvBuff = 0x00; newClient->m_recvSize = 0x00; newClient->m_recvPos = 0x00; *newClient->m_sendBuff = 0x00; newClient->m_sendSize = 0x00; *newClient->m_name = 0x00; newClient->m_lastRecvTime = getTime (); newClient->m_prev = NULL; newClient->m_next = NULL; INSERT_TO_LIST (g_ClientList, newClient, m_prev, m_next); g_TotalClient++; outLog ((char*)"accept new connection: %d [%s]\r\n", newDesc, newClient->m_ip); }
void ExternalSource::configureConnection(const int fd, const char *const handshake, size_t size) { if (!setNonblock(fd)) { logg->logError(__FILE__, __LINE__, "Unable to set nonblock on fh"); handleException(); } if (!mMonitor.add(fd)) { logg->logError(__FILE__, __LINE__, "Unable to add fh to monitor"); handleException(); } // Write the handshake to the circular buffer waitFor(Buffer::MAXSIZE_PACK32 + size - 1); mBuffer.packInt(fd); mBuffer.writeBytes(handshake, size - 1); mBuffer.commit(1); }
LWRESULT Cx_TSFrontend::createTcpServer(int port) { mServerSocket = socket(AF_INET, SOCK_STREAM, 0); if(mServerSocket <= 0) { LWDP_LOG_PRINT("TSFRONTEND", LWDP_LOG_MGR::ERR, "Socket Create Failed"); return TSFRONTEND::LWDP_CREATE_SOCKET_ERR; } setNonblock(mServerSocket); setReuseaddr(mServerSocket); sockaddr_in addr; setAddress("0.0.0.0", port, &addr); int ret = bind(mServerSocket, (struct sockaddr*)&addr, sizeof(addr)); if(ret) { LWDP_LOG_PRINT("TSFRONTEND", LWDP_LOG_MGR::ERR, "Bind(port:%d) Socket Failed", port); return TSFRONTEND::LWDP_BIND_SOCKET_ERR; } GET_OBJECT_RET(ConfigMgr, iConfigMgr, LWDP_GET_OBJECT_ERROR); XPropertys propBlock; iConfigMgr->GetModulePropEntry(LW_TSFRONTEND_MODULE_NAME, LW_TSFRONTEND_MODULE_BLOCK_NAME, propBlock); uint32_ blockNum = LW_TSFRONTEND_BLOCK; if(!propBlock[0].propertyText.empty()) { blockNum = atol(propBlock[0].propertyText.c_str()); } else { LWDP_LOG_PRINT("TSFRONTEND", LWDP_LOG_MGR::WARNING, "Can't Find <ListenBlock> In Config File, Default(%d)", blockNum); } ret = listen(mServerSocket, blockNum); // if(ret) { LWDP_LOG_PRINT("TSFRONTEND", LWDP_LOG_MGR::ERR, "Listen Socket Failed"); return TSFRONTEND::LWDP_LISTEN_SOCKET_ERR; } return LWDP_OK; }
int32_t connector_connect(connector_t c,const char *ip,uint32_t port,on_connect call_back,void *ud,uint32_t ms) { struct sockaddr_in remote; HANDLE sock; struct pending_connect *pc; sock = OpenSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(sock < 0) return -1; remote.sin_family = AF_INET; remote.sin_port = htons(port); if(inet_pton(INET,ip,&remote.sin_addr) < 0) { printf("%s\n",strerror(errno)); return -1; } if(ms>0) { if(setNonblock(sock)!=0) return -1; } if(Connect(sock, (struct sockaddr *)&remote, sizeof(remote)) == 0) { //连接成功,无需要后续处理了,直接调用回调函数 call_back(sock,ip,port,ud); return 0; } socket_t s = GetSocketByHandle(sock); pc = malloc(sizeof(*pc)); pc->lnode.next = NULL; pc->sock = sock; pc->ip = ip; pc->port = port; pc->call_back = call_back; pc->timeout = GetSystemMs() + ms; pc->ud = ud; pc->real_fd = s->fd; mutex_lock(c->lock); LINK_LIST_PUSH_BACK(c->extern_pending_connect,pc); mutex_unlock(c->lock); return 0; }
/* ==================== initialize server socket ==================== */ SOCKET initServerSock (int port, int backLog) { struct sockaddr_in sa; SOCKET sock; sock = socket (PF_INET, SOCK_STREAM, 0); if (sock < 0) { outLog ((char*)"InitServerSock(), socket (..) failed [PORT: %d].. \r\n", port); return (-1); } int opt = 1; if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, \ (char*) &opt, sizeof (opt)) < 0) { outLog ((char*)"* Error: setsockopt REUSEADDR\r\n"); exit (1); } struct linger ld; ld.l_onoff = 0; ld.l_linger = 0; if (setsockopt (sock, SOL_SOCKET, SO_LINGER, \ (char*) &ld, sizeof (ld)) < 0) outLog ((char*)"* Error: setsockopt SO_LINGER ...\r\n"); (void) memset ((char*)&sa, 0x00, sizeof (sa)); sa.sin_family = PF_INET; sa.sin_port = htons (port); sa.sin_addr.s_addr = INADDR_ANY; if (bind (sock, (struct sockaddr*)&sa, sizeof (sa)) < 0) { outLog ((char*)"InitServerSock(), bind (..) failed [PORT: %d].. \r\n", port); CLOSESOCKET (sock); return (-1); } setNonblock (sock); listen (sock, backLog); return (sock); }
bool CMySocket::ConnectServer() { Close(); m_bfirstpack = true; m_bZlib = false; m_zlibIn.Init(); m_zlibDe.Init(); m_sRecvBuf.clear(); struct sockaddr_in peer; if (!set_address(m_szdomian, m_port, &peer)) { g_WriteLog.WriteLog(C_LOG_ERROR, "set_address error, domain:%s, port:%hd", m_szdomian, m_port); return FALSE; } SOCKET s = socket(AF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { int nerrid = WSAGetLastError(); g_WriteLog.WriteLog(C_LOG_ERROR, "create sock error, errno=%d, %s", errno, FormatLastError(nerrid)); return FALSE; } if (connect(s, (struct sockaddr *)&peer, sizeof(peer))) { int nerrid = WSAGetLastError(); g_WriteLog.WriteLog(C_LOG_ERROR, "connect to %s:%hu,errno=%d, %s", m_szdomian, m_port, errno, FormatLastError(nerrid)); closesocket(s); s = INVALID_SOCKET; return FALSE; } setNonblock(s); setNoDelay(s, true); m_hSocket = s; //赋值后导致recv线程开始执行 return m_hSocket != INVALID_SOCKET; }
LogDispatcher::LogDispatcher(Epoll *pEpoll) { assert(pEpoll); m_pEpoll = pEpoll; // set state m_iConnect = CONNECTED; // init EpollEvent m_WriteEpollEvent.setEpoll(m_pEpoll); m_WriteEpollEvent.setHandler(this); // init pipe int fd[2]; int rt = pipe(fd); if (0 != rt) { ERROR_LOG("Syscall Error: pipe. %s", strerror(errno)); } m_QueueRD = fd[0]; m_QueueWR = fd[1]; setNonblock(m_QueueWR); // set fd to epoll m_WriteEpollEvent.setFd(m_QueueWR); m_WriteEpollEvent.registerWEvent(); // close the write event m_WriteEpollEvent.closeWevent(); // start log thread m_pLogThread = new LogThread(); m_pLogThread->setQueueFd(m_QueueRD); m_pLogThread->start(); }
/** * \brief 构造函数,初始化对象 * \param sock 套接口 * \param addr 地址 * \param compress 底层数据传输是否支持压缩 */ zSocket::zSocket( const int sock, const struct sockaddr_in *addr, const bool compress) { //Zebra::logger->trace("zSocket::zSocket"); assert(-1 != sock); this->sock = sock; bzero(&this->addr, sizeof(struct sockaddr_in)); if (NULL == addr) { socklen_t len = sizeof(struct sockaddr); getpeername(this->sock, (struct sockaddr *)&this->addr, &len); } else { bcopy(addr, &this->addr, sizeof(struct sockaddr_in)); } bzero(&this->local_addr, sizeof(struct sockaddr_in)); { socklen_t len = sizeof(struct sockaddr_in); getsockname(this->sock, (struct sockaddr *)&this->local_addr, &len); } fcntl(this->sock, F_SETFD, fcntl(this->sock, F_GETFD, 0) | FD_CLOEXEC); setNonblock(); rd_msec = T_RD_MSEC; wr_msec = T_WR_MSEC; _rcv_raw_size = 0; _current_cmd = 0; set_flag(INCOMPLETE_READ | INCOMPLETE_WRITE); if (compress) bitmask |= PACKET_ZIP; }
void ExternalSource::run() { int pipefd[2]; prctl(PR_SET_NAME, (unsigned long)&"gatord-external", 0, 0, 0); if (pipe_cloexec(pipefd) != 0) { logg->logError(__FILE__, __LINE__, "pipe failed"); handleException(); } mInterruptFd = pipefd[1]; if (!mMonitor.add(pipefd[0])) { logg->logError(__FILE__, __LINE__, "Monitor::add failed"); handleException(); } // Notify annotate clients to retry connecting to gatord gSessionData->annotateListener.signal(); while (gSessionData->mSessionIsActive) { struct epoll_event events[16]; // Clear any pending sem posts while (sem_trywait(&mBufferSem) == 0); int ready = mMonitor.wait(events, ARRAY_LENGTH(events), -1); if (ready < 0) { logg->logError(__FILE__, __LINE__, "Monitor::wait failed"); handleException(); } const uint64_t currTime = getTime(); for (int i = 0; i < ready; ++i) { const int fd = events[i].data.fd; if (fd == mMveStartupUds.getFd()) { // Mali Video Engine says it's alive int client = mMveStartupUds.acceptConnection(); // Don't read from this connection, establish a new connection to Mali-V500 close(client); if (!connectMve()) { logg->logError(__FILE__, __LINE__, "Unable to configure incoming Mali video connection"); handleException(); } } else if (fd == mMaliStartupUds.getFd()) { // Mali Graphics says it's alive int client = mMaliStartupUds.acceptConnection(); // Don't read from this connection, establish a new connection to Mali Graphics close(client); if (!connectMali()) { logg->logError(__FILE__, __LINE__, "Unable to configure incoming Mali graphics connection"); handleException(); } } else if (fd == mAnnotate.getFd()) { int client = mAnnotate.acceptConnection(); if (!setNonblock(client) || !mMonitor.add(client)) { logg->logError(__FILE__, __LINE__, "Unable to set socket options on incoming annotation connection"); handleException(); } } else if (fd == pipefd[0]) { // Means interrupt has been called and mSessionIsActive should be reread } else { /* This can result in some starvation if there are multiple * threads which are annotating heavily, but it is not * recommended that threads annotate that much as it can also * starve out the gator data. */ while (gSessionData->mSessionIsActive) { // Wait until there is enough room for the fd, two headers and two ints waitFor(7*Buffer::MAXSIZE_PACK32 + 2*sizeof(uint32_t)); mBuffer.packInt(fd); const int contiguous = mBuffer.contiguousSpaceAvailable(); const int bytes = read(fd, mBuffer.getWritePos(), contiguous); if (bytes < 0) { if (errno == EAGAIN) { // Nothing left to read mBuffer.commit(currTime); break; } // Something else failed, close the socket mBuffer.commit(currTime); mBuffer.packInt(-1); mBuffer.packInt(fd); mBuffer.commit(currTime); close(fd); break; } else if (bytes == 0) { // The other side is closed mBuffer.commit(currTime); mBuffer.packInt(-1); mBuffer.packInt(fd); mBuffer.commit(currTime); close(fd); break; } mBuffer.advanceWrite(bytes); mBuffer.commit(currTime); // Short reads also mean nothing is left to read if (bytes < contiguous) { break; } } } } } mBuffer.setDone(); if (mMveUds >= 0) { gSessionData->maliVideo.stop(mMveUds); } mInterruptFd = -1; close(pipefd[0]); close(pipefd[1]); }
void *runServer(void* value) { int i = 0; Settings *settings = (Settings *)value; struct sockaddr_in sockAddr; sockAddr.sin_family = AF_INET; sockAddr.sin_port = htons(settings->port); int master = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (0 >= inet_pton(AF_INET, settings->ip, &sockAddr.sin_addr.s_addr)) fprintf(stderr,"ERROR: wrong IP address\n"); bind(master, (struct sockaddr *)(&sockAddr), sizeof(sockAddr)); setNonblock(master); listen(master, SOMAXCONN); int epoll = epoll_create1(0); struct epoll_event epollEvent; epollEvent.data.fd = master; epollEvent.events = EPOLLIN; epoll_ctl(epoll, EPOLL_CTL_ADD, master, &epollEvent); while(1) { struct epoll_event events[EPOLL_SIZE]; int numEvents = epoll_wait(epoll, events, EPOLL_SIZE, -1); for (i = 0; i < numEvents; ++i) { if (events[i].data.fd == master) { int slave = accept (master, 0, 0); struct epoll_event event; event.data.fd = slave; event.events = EPOLLIN; setNonblock (slave); epoll_ctl(epoll, EPOLL_CTL_ADD, slave, &event); } else { char query[BUF_LEN]; memset(query, 0, sizeof(query)); if (0 < recv(events[i].data.fd, query, BUF_LEN, MSG_NOSIGNAL)) { int start = 0; int queryLen = strlen(query); toLog("query src: ", query); while((query[start] != '/') && (start < queryLen)) start++; int finish = start; while((query[finish] != ' ') && (query[finish] != '?') && (finish < queryLen)) finish++; char queryPath[BUF_LEN]; memset(queryPath, 0, sizeof(queryPath)); strcat(queryPath, settings->path); int pathLen = strlen(queryPath); strncpy(queryPath + pathLen, query+start, finish-start); queryPath[pathLen + finish-start] = '\0'; toLog("queryPath: ", queryPath); FILE *f = fopen(queryPath, "r"); struct stat statbuf; stat(queryPath, &statbuf); if((f != NULL) && !S_ISDIR(statbuf.st_mode)) { toLog("TRY to read:", queryPath); char *buf; size_t len; fseek(f, 0, SEEK_END); len = ftell(f); int respLen = strlen(Resp_200); buf = (char *) malloc(len + respLen + 1); memset(buf, 0, sizeof(len + respLen)); strcpy(buf, Resp_200); fseek(f, 0, SEEK_SET); fread(buf + respLen, 1, len, f); fclose(f); buf[len + respLen] = '\0'; toLog("buf send: ", buf); send(events[i].data.fd, buf, strlen(buf), MSG_NOSIGNAL); } else { toLog("WRONG: ", Resp_404); send(events[i].data.fd, Resp_404, strlen(Resp_404), MSG_NOSIGNAL); } shutdown(events[i].data.fd, SHUT_RDWR); close(events[i].data.fd); } else if (errno != EAGAIN) { shutdown(events[i].data.fd, SHUT_RDWR); close(events[i].data.fd); } } } } }
CSocket::CSocket( const SOCKET sock, const struct sockaddr_in *addr, const bool compress, const bool useIocp, CTCPTask* pTask) :m_ovIn( IO_Read), m_ovOut( IO_Write ), m_dwSendCount(0), m_dwRecvCount(0), m_dwMySendCount(0) { printf("新建连接 %0.8X\n", (DWORD)pTask ); m_bIocpDeleted = false; m_bTaskDeleted = false; assert(INVALID_SOCKET != sock); this->m_bUseIocp = useIocp; this->sock = sock; this->pTask = pTask; memset((void *)&this->addr,0,sizeof(struct sockaddr_in)); if (NULL == addr) { int len = sizeof(struct sockaddr); getpeername(this->sock,(struct sockaddr *)&this->addr,&len); } else { //bcopy((void *)addr,&this->addr,sizeof(struct sockaddr_in),sizeof(struct sockaddr_in)); memcpy_s(&this->addr,sizeof(struct sockaddr_in),(void *)addr,sizeof(struct sockaddr_in)); } memset((void *)&this->local_addr,0,sizeof(struct sockaddr_in)); { int len = sizeof(struct sockaddr_in); getsockname(this->sock,(struct sockaddr *)&this->local_addr,&len); } //设置套接口为非阻塞模式 setNonblock(); rd_msec = T_RD_MSEC; wr_msec = T_WR_MSEC; _rcv_raw_size = 0; _current_cmd = 0; // [ranqd]建立接收通知事件 // m_hRecvEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); if( useIocp ) { // [ranqd] 绑定IO到完成端口上 CIocp::getInstance().BindIocpPort( (HANDLE)sock, this ); } set_flag(INCOMPLETE_READ | INCOMPLETE_WRITE); if (compress) bitmask |= PACKET_ZIP; }