static evutil_socket_t createSocket (int family, int nonblock) { evutil_socket_t fd; int ret; fd = socket (family, SOCK_STREAM, 0); if (fd < 0) { ccnet_warning("create Socket failed %d\n", fd); } else if (nonblock) { int nodelay = 1; fd = makeSocketNonBlocking( fd ); ret = setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); if (ret < 0) { ccnet_warning("setsockopt failed\n"); evutil_closesocket(fd); return -1; } } return fd; }
void initServer(struct memcachedServer *server) { server->sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (server->sockfd == -1) { exit(1); } struct sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(server->port); serveraddr.sin_addr.s_addr = INADDR_ANY; //bind the socket to the port if(bind(server->sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) { close(server->sockfd); exit(1); } //listen on the socket if(listen(server->sockfd, BACKLOG) < 0) { close(server->sockfd); exit(1); } if(makeSocketNonBlocking(server->sockfd) < 0 ) { exit(1); } }
void RTSPServer::incomingConnectionHandler1() { struct sockaddr_in clientAddr; SOCKLEN_T clientAddrLen = sizeof clientAddr; // printf("incomingConnectionHandler1\n"); //jay int clientSocket = accept(fServerSocket, (struct sockaddr*)&clientAddr, &clientAddrLen); if (clientSocket < 0) { int err = envir().getErrno(); if (err != EWOULDBLOCK) { envir().setResultErrMsg("accept() failed: "); } return; } makeSocketNonBlocking(clientSocket); increaseSendBufferTo(envir(), clientSocket, 50*1024); #if defined(DEBUG) || defined(DEBUG_CONNECTIONS) envir() << "accept()ed connection from " << our_inet_ntoa(clientAddr.sin_addr) << '\n'; #endif // Create a new object for this RTSP session. // (Choose a random 32-bit integer for the session id (it will be encoded as a 8-digit hex number). We don't bother checking for // a collision; the probability of two concurrent sessions getting the same session id is very low.) unsigned sessionId = (unsigned)our_random(); (void)createNewClientSession(sessionId, clientSocket, clientAddr); }
BasicUDPSource::BasicUDPSource(UsageEnvironment& env, Groupsock* inputGS) : FramedSource(env), fInputGS(inputGS), fHaveStartedReading(False) { // Try to use a large receive buffer (in the OS): increaseReceiveBufferTo(env, inputGS->socketNum(), 50*1024); // Make the socket non-blocking, even though it will be read from only asynchronously, when packets arrive. // The reason for this is that, in some OSs, reads on a blocking socket can (allegedly) sometimes block, // even if the socket was previously reported (e.g., by "select()") as having data available. // (This can supposedly happen if the UDP checksum fails, for example.) makeSocketNonBlocking(fInputGS->socketNum()); }
ByteStreamFileSource::ByteStreamFileSource(UsageEnvironment& env, FILE* fid, Boolean deleteFidOnClose, unsigned preferredFrameSize, unsigned playTimePerFrame) : FramedFileSource(env, fid), fPreferredFrameSize(preferredFrameSize), fPlayTimePerFrame(playTimePerFrame), fLastPlayTime(0), fFileSize(0), fDeleteFidOnClose(deleteFidOnClose), fHaveStartedReading(False), fLimitNumBytesToStream(False), fNumBytesToStream(0) { #ifndef READ_FROM_FILES_SYNCHRONOUSLY makeSocketNonBlocking(fileno(fFid)); #endif }
ByteStreamFileSource::ByteStreamFileSource(UsageEnvironment& env, FILE* fid, unsigned preferredFrameSize, unsigned playTimePerFrame) : FramedFileSource(env, fid), fFileSize(0), fPreferredFrameSize(preferredFrameSize), fPlayTimePerFrame(playTimePerFrame), fLastPlayTime(0), fHaveStartedReading(False), fLimitNumBytesToStream(False), fNumBytesToStream(0) { #ifndef READ_FROM_FILES_SYNCHRONOUSLY makeSocketNonBlocking(fileno(fFid)); #endif // Test whether the file is seekable fFidIsSeekable = FileIsSeekable(fFid); }
evutil_socket_t ccnet_net_accept (evutil_socket_t b, struct sockaddr_storage *cliaddr, socklen_t *len, int nonblock) { evutil_socket_t s; /* int nodelay = 1; */ s = accept (b, (struct sockaddr *)cliaddr, len); /* setsockopt (s, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); */ if (nonblock) makeSocketNonBlocking(s); return s; }
void SocketAcceptor::handleEvent(EventType type) { struct sockaddr clientAddr; socklen_t len = sizeof(clientAddr); int clientfd; clientfd = accept(sockfd_, &clientAddr, &len); //std::cout << "receive connect, id = " << clientfd << std::endl; int ret = makeSocketNonBlocking(clientfd); if (ret == -1) { std::cerr << "set non-blocking error!" << std::endl; abort(); } std::shared_ptr<EventHandler> handler = Singleton<EventHandlerFactory>::instance().createHandler(ECHO_HANDLER, clientfd); Singleton<EventLoopMgr>::instance().registerHandler(handler); }
//可重入函数:处理连接请求 int epollHandleAccept(int _epollFd,int _listenFd) { int clientFd; struct sockaddr_in clientAddr; int c=sizeof(struct sockaddr_in); clientFd=accept(_listenFd,(struct sockaddr *)&clientAddr,(socklen_t *)&c); if(clientFd==-1){ printf("epoll handle accept failed! epollFd: %d listenFd: %d errno: %d\n",_epollFd,_listenFd,errno); return -1; } else{ char str[INET_ADDRSTRLEN]; inet_ntop(AF_INET,&(clientAddr.sin_addr),str,INET_ADDRSTRLEN); printf("epoll %d-listenFd %d accept new connect: fd %d %s:%d\n",_epollFd,_listenFd,clientFd,str,clientAddr.sin_port); //设置新接入的socket为非阻塞 makeSocketNonBlocking(clientFd); //为新接入的socket注册事件 epollAddEvent(_epollFd,clientFd,EPOLLIN|EPOLLET); return clientFd; } }
bool UDP_Socket::initialize(unsigned int port) { if (!initializeSocket()) { printf("Unable to start the socket!\n"); return false; } if (!createSocket(port)) { printf("Unable to create the socket!\n"); return false; } if (!makeSocketNonBlocking()) { printf("Unable to make socket not block!\n"); return false; } //This is old and will need to be depricated. serializedPacketHeaderSize = sizeof(uint32_t) * NUM_PACKET_UINT32 + sizeof(uint16_t) * NUM_PACKET_UINT16 + sizeof(uint8_t) * NUM_PACKET_UINT8; return true; }
void GenericMediaServer::incomingConnectionHandlerOnSocket(int serverSocket) { struct sockaddr_in clientAddr; SOCKLEN_T clientAddrLen = sizeof clientAddr; int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrLen); if (clientSocket < 0) { int err = envir().getErrno(); if (err != EWOULDBLOCK) { envir().setResultErrMsg("accept() failed: "); } return; } ignoreSigPipeOnSocket(clientSocket); // so that clients on the same host that are killed don't also kill us makeSocketNonBlocking(clientSocket); increaseSendBufferTo(envir(), clientSocket, 50*1024); #ifdef DEBUG envir() << "accept()ed connection from " << AddressString(clientAddr).val() << "\n"; #endif // Create a new object for handling this connection: (void)createNewClientConnection(clientSocket, clientAddr); }
void RTSPServer::incomingConnectionHandler1() { struct sockaddr_in clientAddr; SOCKLEN_T clientAddrLen = sizeof clientAddr; int clientSocket = accept(fServerSocket, (struct sockaddr*)&clientAddr, &clientAddrLen); if (clientSocket < 0) { int err = envir().getErrno(); if (err != EWOULDBLOCK) { envir().setResultErrMsg("accept() failed: "); } return; } makeSocketNonBlocking(clientSocket); increaseSendBufferTo(envir(), clientSocket, 50*1024); #if defined(DEBUG) || defined(DEBUG_CONNECTIONS) fprintf(stderr, "accept()ed connection from %s\n", our_inet_ntoa(clientAddr.sin_addr)); #endif // Create a new object for this RTSP session: new RTSPClientSession(*this, ++fSessionIdCounter, clientSocket, clientAddr); }
int setupStreamSocket(UsageEnvironment& env, Port port, Boolean makeNonBlocking) { if (!initializeWinsockIfNecessary()) { socketErr(env, "Failed to initialize 'winsock': "); return -1; } int newSocket = socket(AF_INET, SOCK_STREAM, 0); if (newSocket < 0) { socketErr(env, "unable to create stream socket: "); return newSocket; } if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseFlag, sizeof reuseFlag) < 0) { socketErr(env, "setsockopt(SO_REUSEADDR) error: "); closeSocket(newSocket); return -1; } // SO_REUSEPORT doesn't really make sense for TCP sockets, so we // normally don't set them. However, if you really want to do this // #define REUSE_FOR_TCP #ifdef REUSE_FOR_TCP #if defined(__WIN32__) || defined(_WIN32) // Windoze doesn't properly handle SO_REUSEPORT #else #ifdef SO_REUSEPORT if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuseFlag, sizeof reuseFlag) < 0) { socketErr(env, "setsockopt(SO_REUSEPORT) error: "); closeSocket(newSocket); return -1; } #endif #endif #endif // Note: Windoze requires binding, even if the port number is 0 #if defined(__WIN32__) || defined(_WIN32) #else if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) { #endif MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num()); if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) { char tmpBuffer[100]; sprintf(tmpBuffer, "bind() error (port number: %d): ", ntohs(port.num())); socketErr(env, tmpBuffer); closeSocket(newSocket); return -1; } #if defined(__WIN32__) || defined(_WIN32) #else } #endif if (makeNonBlocking) { if (!makeSocketNonBlocking(newSocket)) { socketErr(env, "failed to make non-blocking: "); closeSocket(newSocket); return -1; } } return newSocket; }
evutil_socket_t ccnet_net_bind_tcp (int port, int nonblock) { #ifndef WIN32 int sockfd, n; struct addrinfo hints, *res, *ressave; char buf[10]; memset (&hints, 0,sizeof (struct addrinfo)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf (buf, sizeof(buf), "%d", port); if ( (n = getaddrinfo(NULL, buf, &hints, &res) ) != 0) { ccnet_warning ("getaddrinfo fails: %s\n", gai_strerror(n)); return -1; } ressave = res; do { int on = 1; sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sockfd < 0) continue; /* error - try next one */ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { ccnet_warning ("setsockopt of SO_REUSEADDR error\n"); continue; } if (nonblock) sockfd = makeSocketNonBlocking (sockfd); if (sockfd < 0) continue; /* error - try next one */ if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0) break; /* success */ close(sockfd); /* bind error - close and try next one */ } while ( (res = res->ai_next) != NULL); freeaddrinfo (ressave); if (res == NULL) { ccnet_warning ("bind fails: %s\n", strerror(errno)); return -1; } return sockfd; #else evutil_socket_t s; struct sockaddr_in sock; const int type = AF_INET; #if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT ) int optval; #endif if ((s = createSocket(type, nonblock)) < 0) return -1; optval = 1; setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(optval)); memset(&sock, 0, sizeof(sock)); sock.sin_family = AF_INET; sock.sin_addr.s_addr = INADDR_ANY; sock.sin_port = htons(port); if ( bind(s, (struct sockaddr *)&sock, sizeof(struct sockaddr_in)) < 0) { ccnet_warning ("bind fails: %s\n", strerror(errno)); evutil_closesocket (s); return -1; } if (nonblock) s = makeSocketNonBlocking (s); return s; #endif }
int listenClients(int _localServerFd) { int clientListenFd=createSocketAndBind(CLIENT_LISTEN_PORT); //设置套接字为非阻塞 int errorCode=0; if((errorCode=makeSocketNonBlocking(clientListenFd))<0){ printf("create client listen scoket failed! errno: %d\n",errno); return -1; } //监听套接字,SOMAXCONN为系统默认的最大连接个数 if((errorCode=listen(clientListenFd,SOMAXCONN))<0){ printf("create client listen scoket failed! errno: %d\n",errno); return -2; } //以下为使用IO多路复用模型函数epool来监控接入 struct epoll_event events[EPOLL_EVENTS_SIZE]; int epollFd; if((epollFd=epoll_create(EPOLL_FD_SIZE))<0){ printf("create epoll failed! errno: %d\n",errno); return -3; } //添加监听描述符事件 epollAddEvent(epollFd,clientListenFd,EPOLLIN|EPOLLET); epollAddEvent(epollFd,_localServerFd,EPOLLIN|EPOLLET); char buffer[SENSORS_DATA_MAX_SIZE]; memset(buffer,'0',SENSORS_DATA_MAX_SIZE); //this is used for record valid client fd std::map<int,int> connectedClientMap; //循环等待 while(1){ int eventsNum=epoll_wait(epollFd,events,EPOLL_EVENTS_SIZE,-1); for(int i=0;i<eventsNum;++i){ //根据事件描述符类型和事件类型进行处理 int fdTmp=events[i].data.fd; uint32_t eventsTmp=events[i].events; // printf("localServerFd:%d clientListenFd:%d fdTmp:%d events: %d EPOLLERR:%d EPOLLHUP:%d EPOLLRDHUP:%d EPOLLIN:%d EPOLLOUT:%d\n",_localServerFd,clientListenFd,fdTmp,eventsTmp,EPOLLERR,EPOLLHUP,EPOLLRDHUP,EPOLLIN,EPOLLOUT); //处理错误和挂起 if((eventsTmp&EPOLLERR)||(eventsTmp&EPOLLHUP)||(eventsTmp&EPOLLRDHUP)){ printf("epoll error occured!\n"); epollHandleError(epollFd,fdTmp,eventsTmp); } //处理有新连接接入 else if((fdTmp==clientListenFd)&&(eventsTmp&EPOLLIN)){ int connectedClient=epollHandleAccept(epollFd,clientListenFd); if(connectedClient>0){ connectedClientMap.insert(std::pair<int,int>(connectedClient,connectedClient)); } } //this is used for read local client in background process 's data else if((fdTmp==_localServerFd)&&(eventsTmp&EPOLLIN)){ memset(buffer,'\0',SENSORS_DATA_MAX_SIZE); int nRecv=recv(_localServerFd,buffer,SENSORS_DATA_MAX_SIZE,0); if(nRecv==SENSORS_DATA_FRAME_SIZE){ for(int i=0;i<SENSORS_DATA_FRAME_SIZE;++i){ // printf("|%c",buffer[i]); } printf("valid client fd: "); for(std::map<int,int>::iterator it=connectedClientMap.begin();it!=connectedClientMap.end();++it){ printf("%d ",it->second); send(it->second,buffer,SENSORS_DATA_FRAME_SIZE,0); } printf("\n"); } else{ printf("local client received %d bytes errno: %d\n",nRecv,errno); } } //this is used for handle other client's data else if(eventsTmp&EPOLLIN){ if(epollHandleRead(epollFd,fdTmp,buffer,SENSORS_DATA_MAX_SIZE)<0){ //read error occured! remove fd from valid connected map connectedClientMap.erase(fdTmp); } } else if(eventsTmp&EPOLLOUT){ // epollHandleWrite(epollFd,fdTmp,buffer,SENSORS_DATA_MAX_SIZE); } } } free(events); close(clientListenFd); return 0; }
WAVAudioFileSource::WAVAudioFileSource(UsageEnvironment& env, FILE* fid) : AudioInputDevice(env, 0, 0, 0, 0)/* set the real parameters later */, fFid(fid), fFidIsSeekable(False), fLastPlayTime(0), fHaveStartedReading(False), fWAVHeaderSize(0), fFileSize(0), fScaleFactor(1), fLimitNumBytesToStream(False), fNumBytesToStream(0), fAudioFormat(WA_UNKNOWN) { // Check the WAV file header for validity. // Note: The following web pages contain info about the WAV format: // http://www.ringthis.com/dev/wave_format.htm // http://www.lightlink.com/tjweber/StripWav/Canon.html // http://www.onicos.com/staff/iz/formats/wav.html Boolean success = False; // until we learn otherwise do { // RIFF Chunk: if (nextc != 'R' || nextc != 'I' || nextc != 'F' || nextc != 'F') break; if (!skipBytes(fid, 4)) break; if (nextc != 'W' || nextc != 'A' || nextc != 'V' || nextc != 'E') break; // Skip over any chunk that's not a FORMAT ('fmt ') chunk: u_int32_t tmp; if (!get4Bytes(fid, tmp)) break; while (tmp != 0x20746d66/*'fmt ', little-endian*/) { // Skip this chunk: u_int32_t chunkLength; if (!get4Bytes(fid, chunkLength)) break; if (!skipBytes(fid, chunkLength)) break; if (!get4Bytes(fid, tmp)) break; } // FORMAT Chunk (the 4-byte header code has already been parsed): unsigned formatLength; if (!get4Bytes(fid, formatLength)) break; unsigned short audioFormat; if (!get2Bytes(fid, audioFormat)) break; fAudioFormat = (unsigned char)audioFormat; if (fAudioFormat != WA_PCM && fAudioFormat != WA_PCMA && fAudioFormat != WA_PCMU && fAudioFormat != WA_IMA_ADPCM) { // It's a format that we don't (yet) understand env.setResultMsg("Audio format is not one that we handle (PCM/PCMU/PCMA or IMA ADPCM)"); break; } unsigned short numChannels; if (!get2Bytes(fid, numChannels)) break; fNumChannels = (unsigned char)numChannels; if (fNumChannels < 1 || fNumChannels > 2) { // invalid # channels char errMsg[100]; sprintf(errMsg, "Bad # channels: %d", fNumChannels); env.setResultMsg(errMsg); break; } if (!get4Bytes(fid, fSamplingFrequency)) break; if (fSamplingFrequency == 0) { env.setResultMsg("Bad sampling frequency: 0"); break; } if (!skipBytes(fid, 6)) break; // "nAvgBytesPerSec" (4 bytes) + "nBlockAlign" (2 bytes) unsigned short bitsPerSample; if (!get2Bytes(fid, bitsPerSample)) break; fBitsPerSample = (unsigned char)bitsPerSample; if (fBitsPerSample == 0) { env.setResultMsg("Bad bits-per-sample: 0"); break; } if (!skipBytes(fid, formatLength - 16)) break; // FACT chunk (optional): int c = nextc; if (c == 'f') { if (nextc != 'a' || nextc != 'c' || nextc != 't') break; unsigned factLength; if (!get4Bytes(fid, factLength)) break; if (!skipBytes(fid, factLength)) break; c = nextc; } // EYRE chunk (optional): if (c == 'e') { if (nextc != 'y' || nextc != 'r' || nextc != 'e') break; unsigned eyreLength; if (!get4Bytes(fid, eyreLength)) break; if (!skipBytes(fid, eyreLength)) break; c = nextc; } // DATA Chunk: if (c != 'd' || nextc != 'a' || nextc != 't' || nextc != 'a') break; if (!skipBytes(fid, 4)) break; // The header is good; the remaining data are the sample bytes. fWAVHeaderSize = (unsigned)TellFile64(fid); success = True; } while (0); if (!success) { env.setResultMsg("Bad WAV file format"); // Set "fBitsPerSample" to zero, to indicate failure: fBitsPerSample = 0; return; } fPlayTimePerSample = 1e6/(double)fSamplingFrequency; // Although PCM is a sample-based format, we group samples into // 'frames' for efficient delivery to clients. Set up our preferred // frame size to be close to 20 ms, if possible, but always no greater // than 1400 bytes (to ensure that it will fit in a single RTP packet) unsigned maxSamplesPerFrame = (1400*8)/(fNumChannels*fBitsPerSample); unsigned desiredSamplesPerFrame = (unsigned)(0.02*fSamplingFrequency); unsigned samplesPerFrame = desiredSamplesPerFrame < maxSamplesPerFrame ? desiredSamplesPerFrame : maxSamplesPerFrame; fPreferredFrameSize = (samplesPerFrame*fNumChannels*fBitsPerSample)/8; fFidIsSeekable = FileIsSeekable(fFid); #ifndef READ_FROM_FILES_SYNCHRONOUSLY // Now that we've finished reading the WAV header, all future reads (of audio samples) from the file will be asynchronous: makeSocketNonBlocking(fileno(fFid)); #endif }
int startUpServer(void) { //两个进程:前台进程监听客户端设备,后台进程监听采集设备 pid_t processId=fork(); if(processId==0){ //插入延时确保前台本地服务进程创建成功 usleep(10000); //建立前台和后台进程间传送数据的本地socket连接 int localClientFd; struct sockaddr_in localServerAddr; localClientFd=socket(AF_INET,SOCK_STREAM,0); if(makeSocketNonBlocking(localClientFd)<0){ printf("create local client socket failed! errno: %d\n",errno); exit(-1); } //设置端口可复用,否则上次程序结束后再重启会导致绑定不成功 int flag=1; if(setsockopt(localClientFd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag))<0){ printf("create local client socket failed! errno: %d\n",errno); exit(-2); } if(setsockopt(localClientFd,IPPROTO_TCP,TCP_NODELAY,&flag,sizeof(flag))<0){ printf("create local client socket failed!errno:%d\n",errno); exit(-3); } memset(&localServerAddr,0,sizeof(localServerAddr)); localServerAddr.sin_addr.s_addr=inet_addr("127.0.0.1"); localServerAddr.sin_family=AF_INET; localServerAddr.sin_port=htons(LOCAL_LISTEN_PORT); //连接本地服务器 int errorCode=0; while((errorCode=connect(localClientFd,(struct sockaddr *)&localServerAddr,sizeof(localServerAddr)))<0){ printf("create local client failed! errno: %d\n",errno); usleep(10000); // exit(-2); } printf("create local client success!\n"); //监听传感设备 listenSensors(localClientFd); exit(0); } else{ //建立前台和后台进程间传送数据的本地socket连接 int localServerFd=createSocketAndBind(LOCAL_LISTEN_PORT); //监听套接字 int errorCode=0; if((errorCode=listen(localServerFd,1))<0){ printf("create local server failed! errno: %d\n",errno); exit(-2); } printf("create local server success! waiting for client....\n"); //等待后台进程的连接 int localClientFd; struct sockaddr_in localClientAddr; int c=sizeof(struct sockaddr_in); if((localClientFd=accept(localServerFd,(struct sockaddr *)&localClientAddr,(socklen_t *)&c))<0){ printf("create local server failed! errno: %d\n",errno); exit(-3); } makeSocketNonBlocking(localClientFd); usleep(100000); //监听客户端 listenClients(localClientFd); exit(0); } }
int listenSensors(int _localClientFd) { //建立监听传感器设备的套接字 int sensorsListenFd=createSocketAndBind(DEVICE_LISTEN_PORT); //设置套接字为非阻塞 int errorCode=0; if((errorCode=makeSocketNonBlocking(sensorsListenFd))<0){ printf("create sensors listen scoket failed! errno: %d\n",errno); return -1; } //监听套接字,SOMAXCONN为系统默认的最大连接个数 if((errorCode=listen(sensorsListenFd,SOMAXCONN))<0){ printf("create sensors listen scoket failed! errno: %d\n",errno); return -2; } //以下为使用IO多路复用模型函数epool来监控设备的接入 struct epoll_event events[EPOLL_EVENTS_SIZE]; int epollFd; if((epollFd=epoll_create(EPOLL_FD_SIZE))<0){ printf("create epoll failed! errno: %d\n",errno); return -3; } //添加监听描述符事件 epollAddEvent(epollFd,sensorsListenFd,EPOLLIN|EPOLLET); char buffer[SENSORS_DATA_MAX_SIZE]; memset(buffer,'A',SENSORS_DATA_MAX_SIZE); std::map<int,int> connectedSensorMap; //循环等待 while(1){ int eventsNum=epoll_wait(epollFd,events,EPOLL_EVENTS_SIZE,-1); for(int i=0;i<eventsNum;++i){ //根据事件描述符类型和事件类型进行处理 int fdTmp=events[i].data.fd; //处理错误和挂起 if(events[i].events&(EPOLLERR|EPOLLHUP|EPOLLRDHUP)){ epollHandleError(epollFd,fdTmp,events[i].events); } //处理有新连接接入 else if((fdTmp==sensorsListenFd)&&(events[i].events&EPOLLIN)){ int connectedSensor=epollHandleAccept(epollFd,sensorsListenFd); if(connectedSensor>0){ connectedSensorMap.insert(std::pair<int,int>(connectedSensor,connectedSensor)); } } else if(events[i].events&EPOLLIN){ int nRecv=epollHandleRead(epollFd,fdTmp,buffer,SENSORS_DATA_MAX_SIZE); if(nRecv==SENSORS_DATA_FRAME_SIZE){ send(_localClientFd,buffer,SENSORS_DATA_FRAME_SIZE,0); } else if(nRecv<0){ connectedSensorMap.erase(fdTmp); } printf("valid sensor fd: "); for(std::map<int,int>::iterator it=connectedSensorMap.begin();it!=connectedSensorMap.end();++it){ printf("%d ",it->second); } printf("\n"); } else if(events[i].events&EPOLLOUT){ // epollHandleWrite(epollFd,fdTmp,buffer,SENSORS_DATA_MAX_SIZE); } } } free(events); close(sensorsListenFd); return 0; }
void runServer(void *arg) { struct memcachedServer *server = (struct memcachedServer *)arg; fd_set rfds, master; FD_ZERO(&rfds); FD_ZERO(&master); FD_SET(server->sockfd, &master); int sfd, new_fd, fd_max, first_conn_fd = 0; int ii; fd_max = server->sockfd; makeSocketNonBlocking(server->sockfd); rfds = master; while(1) { if(select(fd_max+1, &rfds, NULL, NULL, NULL) < 0){ fprintf(stderr, "error on select"); exit(1); } fprintf(stderr, "\n Got a new event on the server socket!!"); for (ii = 0; ii <= fd_max; ii++) { if (FD_ISSET(ii, &rfds)) { if (ii == server->sockfd) { fprintf(stderr, "\n Accepting a new connection on port %d", server->port); //Accept new client connection struct sockaddr_in caddr; socklen_t addrlen; new_fd = accept(server->sockfd, (struct sockaddr *)&caddr, &addrlen); if(new_fd < 0) { fprintf(stderr, "Unable to accept new connection"); exit(1); } else { fprintf(stderr, "\n New connection %d", new_fd); } //store the starting fd for connections if(server->startfd == 0) { server->startfd = new_fd; } conn *c = conn_new(new_fd); if(server->ctx) { SSL *ssl = SSL_new(server->ctx); SSL_set_accept_state(ssl); SSL_set_fd(ssl, new_fd); fprintf(stderr, "\n Trying the SSL Handshake on fd %d", new_fd); //Doing a blocking SSL handshake int ret = SSL_accept(ssl); if (ret != 1) { int err = SSL_get_error(ssl, ret); while (err == SSL_ERROR_WANT_READ) { ret = SSL_accept(ssl); err = SSL_get_error(ssl, ret); } if(err == SSL_ERROR_ZERO_RETURN || err == SSL_ERROR_SYSCALL) { fprintf(stderr, "\n SSL library errored"); //destroy_conn(c); close(new_fd); continue; } if(err == SSL_ERROR_NONE) { fprintf(stderr, "\n Successfully completed SSL handshake"); } sslObjs[counter_ssl_objects] = ssl; fprintf(stderr, "\n Successfully loaded fd %d", new_fd - server->startfd); } } makeSocketNonBlocking(new_fd); if (new_fd > fd_max) { fd_max = new_fd; } FD_SET(new_fd, &master); } else { fprintf(stderr, "Got an event from the connections \n"); //close(ii); //FD_CLR(ii, &master); //read request from client socket if(server->ctx) { int j = 0; for(j = 0; j < MAX_CLIENT_CONNS ; j++) { if(SSL_get_fd(sslObjs[j]) == ii) { if(handleSSLClientRead(sslObjs[j]) < 0) { fprintf(stderr, "\n Client read failed"); close(ii); FD_CLR(ii, &master); } break; } } } else { if(handleClientRead(ii) < 0) { close(ii); FD_CLR(ii, &master); } } } } } //reload the read fds as select changes the fds rfds = master; } }