int listenToPort( char *bindaddr, int port, int* fds , int *count ) { char neterr[1024]; int tcp_backlog; if (bindaddr == NULL) { /* Bind * for both IPv6 and IPv4, we enter here only if * * server.bindaddr_count == 0. */ fds[*count] = anetTcp6Server( neterr,port,NULL,tcp_backlog); if (fds[*count] != -1) { anetNonBlock(NULL,fds[*count]); (*count)++; } fds[*count] = anetTcpServer( neterr,port,NULL,tcp_backlog); if (fds[*count] != ANET_ERR) { anetNonBlock(NULL,fds[*count]); (*count)++; } /* Exit the loop if we were able to bind * on IPv4 or IPv6, * * otherwise fds[*count] will be ANET_ERR and we'll print an * * error and return to the caller with an error. */ if (*count) { return 1; } } else if (strchr(bindaddr,':')) { /* Bind IPv6 address. */ fds[*count] = anetTcp6Server( neterr,port, bindaddr,tcp_backlog); } else { /* Bind IPv4 address. */ fds[*count] = anetTcpServer(neterr,port,bindaddr,tcp_backlog); } if (fds[*count] == -1) { printf( "Creating Server TCP listening socket %s:%d: %s", bindaddr ? bindaddr : "*", port, neterr); return -1; } anetNonBlock(NULL,fds[*count]); (*count)++; return 1; }
proxy_client*AllocClient(int fd) { proxy_client*c=malloc(sizeof(proxy_client)); if(c==NULL) return NULL; c->flags=0; anetNonBlock(NULL,fd); anetTcpNoDelay(NULL,fd); c->fd=fd; c->blist=AllocBufferList(3); c->remote=AllocRemote(c); c->OnError=FreeClient; c->OnRemoteDown=CloseAfterSent; if(c->remote==NULL){ //bug:c->blist should free close(fd); free(c); return NULL; } LogDebug("New client fd:%d remotefd:%d",c->fd,c->remote->fd); return c; }
client *createClient(int fd) { client *c = malloc(sizeof(client)); anetNonBlock(NULL,fd); anetEnableTcpNoDelay(NULL,fd); if (server.tcpkeepalive) anetKeepAlive(NULL,fd,server.tcpkeepalive); if (aeCreateFileEvent(server.el,fd,AE_READABLE, readQueryFromClient, c) == AE_ERR) { close(fd); free(c); return NULL; } c->id = server.next_client_id++; c->fd = fd; c->name = NULL; c->bufpos = 0; c->querybuf = sdsempty(); c->querybuf_peak = 0; c->reqtype = 0; c->argc = 0; c->argv = NULL; c->lastcmd = NULL; c->multibulklen = 0; c->bulklen = -1; c->sentlen = 0; c->flags = 0; c->ctime = c->lastinteraction = server.unixtime; if (fd != -1) listAddNodeTail(server.clients,c); return c; }
int main(int argc, char** argv) { signal(SIGABRT, &sighandler); signal(SIGTERM, &sighandler); signal(SIGINT, &sighandler); initServer(); aeEventLoop* eventLoop = aeCreateEventLoop(server.max_process_client + SHTTPSVR_EVENTLOOP_FDSET_INCR); server.el = eventLoop; int listen_socket = anetTcpServer(NULL, 80, NULL, server.tcp_backlog); anetNonBlock(NULL, listen_socket); if (listen_socket > 0 && AE_ERR == aeCreateFileEvent(eventLoop, listen_socket, AE_READABLE, tAcceptProc, NULL)) { ERRLOG("aeCreateFileEvent error!"); exit(1); } aeSetBeforeSleepProc(eventLoop, tBeforeSleepProc); initTimeEvent(eventLoop); aeMain(eventLoop); aeDeleteEventLoop(eventLoop); return 0; }
int anetUdpServer(char *err, char *bindaddr, int port) { int sockfd; struct sockaddr_in sa; sockfd=socket(AF_INET,SOCK_DGRAM,0); if(!sockfd) { anetSetError(err, "creating socket: %s", strerror(errno)); return ANET_ERR; } memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr=htonl(INADDR_ANY); sa.sin_port= htons(port); if (bindaddr && inet_aton(bindaddr, &sa.sin_addr) == 0) { anetSetError(err, "invalid bind address"); close(sockfd); return ANET_ERR; } if (anetNonBlock(err, sockfd) != ANET_OK) { return ANET_ERR; } if(bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { anetSetError(err, "bind: %s", strerror(errno)); close(sockfd); return ANET_ERR; } return sockfd; }
// //========================================================================= // // This function gets called from time to time when the decoding thread is // awakened by new data arriving. This usually happens a few times every second // struct client * modesAcceptClients(void) { int fd, port; unsigned int j; struct client *c; for (j = 0; j < MODES_NET_SERVICES_NUM; j++) { if (services[j].enabled) { fd = anetTcpAccept(Modes.aneterr, *services[j].socket, NULL, &port); if (fd == -1) continue; anetNonBlock(Modes.aneterr, fd); c = (struct client *) malloc(sizeof(*c)); c->service = *services[j].socket; c->next = Modes.clients; c->fd = fd; c->buflen = 0; Modes.clients = c; anetSetSendBuffer(Modes.aneterr,fd, (MODES_NET_SNDBUF_SIZE << Modes.net_sndbuf_size)); if (*services[j].socket == Modes.sbsos) Modes.stat_sbs_connections++; if (*services[j].socket == Modes.ros) Modes.stat_raw_connections++; if (*services[j].socket == Modes.bos) Modes.stat_beast_connections++; j--; // Try again with the same listening port if (Modes.debug & MODES_DEBUG_NET) printf("Created new client %d\n", fd); } } return Modes.clients; }
// // ============================= Networking ============================= // // Note: here we disregard any kind of good coding practice in favor of // extreme simplicity, that is: // // 1) We only rely on the kernel buffers for our I/O without any kind of // user space buffering. // 2) We don't register any kind of event handler, from time to time a // function gets called and we accept new connections. All the rest is // handled via non-blocking I/O and manually polling clients to see if // they have something new to share with us when reading is needed. // //========================================================================= // // Networking "stack" initialization // void modesInitNet(void) { struct { char *descr; int *socket; int port; } services[6] = { {"Raw TCP output", &Modes.ros, Modes.net_output_raw_port}, {"Raw TCP input", &Modes.ris, Modes.net_input_raw_port}, {"Beast TCP output", &Modes.bos, Modes.net_output_beast_port}, {"Beast TCP input", &Modes.bis, Modes.net_input_beast_port}, {"HTTP server", &Modes.https, Modes.net_http_port}, {"Basestation TCP output", &Modes.sbsos, Modes.net_output_sbs_port} }; int j; memset(Modes.clients,0,sizeof(Modes.clients)); Modes.maxfd = -1; for (j = 0; j < 6; j++) { int s = anetTcpServer(Modes.aneterr, services[j].port, NULL); if (s == -1) { fprintf(stderr, "Error opening the listening port %d (%s): %s\n", services[j].port, services[j].descr, strerror(errno)); exit(1); } anetNonBlock(Modes.aneterr, s); *services[j].socket = s; } signal(SIGPIPE, SIG_IGN); }
void initServer(char *host, int port) { char *msg; int listendfd = anetTcpServer(msg, port, host); if (listendfd <= 0) { lookup_log(LOG_DEBUG, "create server error %s\n", msg); exit(0); } lookup_log(LOG_DEBUG, "listened %s:%d\n", host, port); if (anetNonBlock(msg, listendfd) < 0) { lookup_log(LOG_DEBUG, "set noblocking server error %s\n", msg); exit(0); } pool = create_event(1024); add_event(pool, listendfd, EPOLLIN, serverAccept); while (1) { lookup_log(LOG_DEBUG, "polling\n"); int num = handle_event(pool, 30); int i; for (i=0; i<num; i++) { int fd = pool->epollEv[i].data.fd; noti_chain_callback cb = pool->events[fd].cb; (*cb) (&pool->events[fd], fd); } } close(listendfd); }
int anetUnixGenericConnect(char *err, char *path, int flags) { int s; struct sockaddr_un sa; if ((s = anetCreateSocket(err,AF_LOCAL)) == ANET_ERR) return ANET_ERR; sa.sun_family = AF_LOCAL; strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1); if (flags & ANET_CONNECT_NONBLOCK) { if (anetNonBlock(err,s) != ANET_OK) return ANET_ERR; } if (connect(s,(struct sockaddr*)&sa,sizeof(sa)) == -1) { if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) return s; anetSetError(err, "connect: %s", strerror(errno)); close(s); return ANET_ERR; } return s; }
redisClient *createClient(int fd) { redisClient *c = zmalloc(sizeof(redisClient)); /* passing -1 as fd it is possible to create a non connected client. * This is useful since all the Redis commands needs to be executed * in the context of a client. When commands are executed in other * contexts (for instance a Lua script) we need a non connected client. */ if (fd != -1) { anetNonBlock(NULL,fd); anetEnableTcpNoDelay(NULL,fd); if (server.tcpkeepalive) anetKeepAlive(NULL,fd,server.tcpkeepalive); if (aeCreateFileEvent(server.el,fd,AE_READABLE, readQueryFromClient, c) == AE_ERR) { close(fd); zfree(c); return NULL; } } selectDb(c,0); c->fd = fd; c->name = NULL; c->bufpos = 0; c->querybuf = sdsempty(); c->querybuf_peak = 0; c->reqtype = 0; c->argc = 0; c->argv = NULL; c->cmd = c->lastcmd = NULL; c->multibulklen = 0; c->bulklen = -1; c->sentlen = 0; c->flags = 0; c->ctime = c->lastinteraction = server.unixtime; c->authenticated = 0; c->replstate = REDIS_REPL_NONE; c->slave_listening_port = 0; c->reply = listCreate(); c->reply_bytes = 0; c->obuf_soft_limit_reached_time = 0; listSetFreeMethod(c->reply,decrRefCount); listSetDupMethod(c->reply,dupClientReplyValue); c->bpop.keys = dictCreate(&setDictType,NULL); c->bpop.timeout = 0; c->bpop.target = NULL; c->io_keys = listCreate(); c->watched_keys = listCreate(); listSetFreeMethod(c->io_keys,decrRefCount); c->pubsub_channels = dictCreate(&setDictType,NULL); c->pubsub_patterns = listCreate(); listSetFreeMethod(c->pubsub_patterns,decrRefCount); listSetMatchMethod(c->pubsub_patterns,listMatchObjects); if (fd != -1) listAddNodeTail(server.clients,c); initClientMultiState(c); return c; }
/** * return a socket defined by (addr, port, flags) * @param addr: address * @param port: port * @param flags: ANET_CONECT_NON/ANET_CONNECT_NONBLOCK to specify block or nonblock type */ static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) { int s, on = 1; struct sockaddr_in sa; /** * create a tcp socket */ if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { anetSetError(err, "creating socket: %s\n", strerror(errno)); return ANET_ERR; } /* Make sure connection-intensive things like the redis benckmark * will be able to close/open sockets a zillion of times */ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); /** * set up sa using addr and port */ sa.sin_family = AF_INET; sa.sin_port = htons(port); if (inet_aton(addr, &sa.sin_addr) == 0) { struct hostent *he; he = gethostbyname(addr); if (he == NULL) { anetSetError(err, "can't resolve: %s\n", addr); close(s); return ANET_ERR; } memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); } /** * set nonblock flag */ if (flags & ANET_CONNECT_NONBLOCK) { if (anetNonBlock(err,s) != ANET_OK) return ANET_ERR; } /** * connect to sa{addr:port} */ if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { /** * nonblock type and we are inprogress, return the current socket */ if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) return s; anetSetError(err, "connect: %s\n", strerror(errno)); close(s); return ANET_ERR; } return s; }
static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) { int s = ANET_ERR, rv; char portstr[6]; /* strlen("65535") + 1; */ struct addrinfo hints, *servinfo, *p; snprintf(portstr,sizeof(portstr),"%d",port); memset(&hints,0,sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((rv = getaddrinfo(addr,portstr,&hints,&servinfo)) != 0) { anetSetError(err, "%s", gai_strerror(rv)); return ANET_ERR; } for (p = servinfo; p != NULL; p = p->ai_next) { /* Try to create the socket and to connect it. * If we fail in the socket() call, or on connect(), we retry with * the next entry in servinfo. */ //如果当前连接不成功,则换下一个连接 if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) continue; if (anetSetReuseAddr(err,s) == ANET_ERR) goto error; //在这里通过传入的flag判断是阻塞还是非阻塞的模式 if (flags & ANET_CONNECT_NONBLOCK && anetNonBlock(err,s) != ANET_OK) goto error; //在这里调连接方法 if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { /* If the socket is non-blocking, it is ok for connect() to * return an EINPROGRESS error here. */ if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) goto end; close(s); s = ANET_ERR; continue; } /* If we ended an iteration of the for loop without errors, we * have a connected socket. Let's return to the caller. */ goto end; } if (p == NULL) anetSetError(err, "creating socket: %s", strerror(errno)); //下面的goto语句执行特定情况处理 error: if (s != ANET_ERR) { close(s); s = ANET_ERR; } end: freeaddrinfo(servinfo); return s; }
static void acceptCommonHandler(int fd, int flags, char *ip) { client *c = (client *)zmalloc(sizeof(client)); c->fd = fd; if (aeCreateFileEvent(server.el, fd, AE_READABLE, readClient, (void *) c) == AE_ERR) { close(fd); zfree(c); return; } anetNonBlock(NULL, fd); return; }
void acceptCommonHandler( aeServer* serv ,int fd,char* client_ip,int client_port, int flags) { if( serv->connectNum >= serv->maxConnect ) { printf( "connect num over limit \n"); close( fd ); return; } if( fd <= 0 ) { printf( "error fd is null\n"); close(fd ); return; } serv->connlist[fd].client_ip = client_ip; serv->connlist[fd].client_port = client_port; serv->connlist[fd].flags |= flags; serv->connlist[fd].fd = fd; serv->connlist[fd].disable = 0; serv->connlist[fd].send_buffer = sdsempty(); int reactor_id = fd % serv->reactorNum; int worker_id = fd % serv->workerNum; if (fd != -1) { anetNonBlock(NULL,fd); anetEnableTcpNoDelay(NULL,fd); aeEventLoop* el = serv->reactorThreads[reactor_id].reactor.eventLoop; if (aeCreateFileEvent( el ,fd,AE_READABLE, onClientReadable, &fd ) == AE_ERR ) { printf( "CreateFileEvent read error fd =%d,errno=%d,errstr=%s \n" ,fd , errno, strerror( errno ) ); close(fd); } aePipeData data = {0}; data.type = PIPE_EVENT_CONNECT; data.connfd = fd; data.len = 0; serv->connectNum += 1; setPipeWritable( el , NULL , worker_id ); int sendlen = PIPE_DATA_HEADER_LENG; pthread_mutex_lock( &servG->workers[worker_id].w_mutex ); servG->workers[worker_id].send_buffer = sdscatlen( servG->workers[worker_id].send_buffer , &data, sendlen ); pthread_mutex_unlock( &servG->workers[worker_id].w_mutex ); } }
int serverAccept(event *v, int fd) { char *msg; char clientHost[32]; int clientPort, clientFd; if ((clientFd = anetTcpAccept(msg, fd, &clientHost[0], &clientPort)) > 0) { lookup_log(LOG_DEBUG, "accept %s:%d fd:%d\n", clientHost, clientPort, clientFd); if (anetNonBlock(msg, clientFd) < 0) { return -1; } add_event(pool, clientFd, EPOLLIN, serverRead); } return 0; }
// //========================================================================= // // This function gets called from time to time when the decoding thread is // awakened by new data arriving. This usually happens a few times every second // void modesAcceptClients(void) { int fd, port; unsigned int j; struct client *c; int services[6]; services[0] = Modes.ros; services[1] = Modes.ris; services[2] = Modes.bos; services[3] = Modes.bis; services[4] = Modes.https; services[5] = Modes.sbsos; for (j = 0; j < sizeof(services)/sizeof(int); j++) { fd = anetTcpAccept(Modes.aneterr, services[j], NULL, &port); if (fd == -1) continue; if (fd >= MODES_NET_MAX_FD) { close(fd); return; // Max number of clients reached } anetNonBlock(Modes.aneterr, fd); c = (struct client *) malloc(sizeof(*c)); c->service = services[j]; c->fd = fd; c->buflen = 0; Modes.clients[fd] = c; anetSetSendBuffer(Modes.aneterr,fd,MODES_NET_SNDBUF_SIZE); if (Modes.maxfd < fd) Modes.maxfd = fd; if (services[j] == Modes.sbsos) Modes.stat_sbs_connections++; if (services[j] == Modes.ros) Modes.stat_raw_connections++; if (services[j] == Modes.bos) Modes.stat_beast_connections++; if (services[j] == Modes.sbsos) { // Send current traffic, if any, immediately int len; char *sbsmsg = aircraftsToSBS(&len); if (sbsmsg) { write(fd, sbsmsg, len); free(sbsmsg); } } j--; // Try again with the same listening port if (Modes.debug & MODES_DEBUG_NET) printf("Created new client %d\n", fd); } }
void createWorkerProcess( aeServer* serv ) { char* neterr; int ret,i; for( i = 0; i < serv->workerNum; i++ ) { //3缓冲区 serv->workers[i].send_buffer = sdsempty(); //init mutex pthread_mutex_init( &(serv->workers[i].r_mutex) ,NULL); pthread_mutex_init( &(serv->workers[i].w_mutex) ,NULL); ret = socketpair( PF_UNIX, SOCK_STREAM, 0, serv->workers[i].pipefd ); assert( ret != -1 ); serv->workers[i].pid = fork(); if( serv->workers[i].pid < 0 ) { continue; } else if( serv->workers[i].pid > 0 ) { //父进程 close( serv->workers[i].pipefd[1] ); anetNonBlock( neterr , serv->workers[i].pipefd[0] ); continue; } else { //子进程 close( serv->workers[i].pipefd[0] ); anetNonBlock( neterr, serv->workers[i].pipefd[1] ); runWorkerProcess( i , serv->workers[i].pipefd[1] ); exit( 0 ); } } }
Sock *sock_init(int fd, int sendbufsize, int recvbufsize) { Sock *s = (Sock *)malloc(sizeof(Sock)); s->fd = fd; s->sendbuf = cb_init(sendbufsize); s->recvbuf = cb_init(recvbufsize); s->missed_packets = 0; anetNonBlock(NULL, fd); return s; }
redisClient *createClient(int fd) { redisClient *c = zmalloc(sizeof(redisClient)); c->bufpos = 0; anetNonBlock(NULL,fd); anetTcpNoDelay(NULL,fd); if (!c) return NULL; if (aeCreateFileEvent(server.el,fd,AE_READABLE, readQueryFromClient, c) == AE_ERR) { #ifdef _WIN32 closesocket(fd); #else close(fd); #endif zfree(c); return NULL; } selectDb(c,0); c->fd = fd; c->querybuf = sdsempty(); c->reqtype = 0; c->argc = 0; c->argv = NULL; c->multibulklen = 0; c->bulklen = -1; c->sentlen = 0; c->flags = 0; c->lastinteraction = time(NULL); c->authenticated = 0; c->replstate = REDIS_REPL_NONE; c->reply = listCreate(); listSetFreeMethod(c->reply,decrRefCount); listSetDupMethod(c->reply,dupClientReplyValue); c->bpop.keys = NULL; c->bpop.count = 0; c->bpop.timeout = 0; c->bpop.target = NULL; c->io_keys = listCreate(); c->watched_keys = listCreate(); listSetFreeMethod(c->io_keys,decrRefCount); c->pubsub_channels = dictCreate(&setDictType,NULL); c->pubsub_patterns = listCreate(); listSetFreeMethod(c->pubsub_patterns,decrRefCount); listSetMatchMethod(c->pubsub_patterns,listMatchObjects); listAddNodeTail(server.clients,c); initClientMultiState(c); return c; }
static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) { int s, on = 1; struct sockaddr_in sa; if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { anetSetError(err, "creating socket: %s\n", strerror(errno)); return ANET_ERR; } /* Make sure connection-intensive things like the redis benckmark * will be able to close/open sockets a zillion of times */ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); struct timeval timeout = { 2, 0 }; setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(struct timeval)); setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(struct timeval)); sa.sin_family = AF_INET; sa.sin_port = htons(port); if (inet_aton(addr, &sa.sin_addr) == 0) { struct hostent *he; pthread_mutex_lock (&mymutex); // add by qfdai2 he = gethostbyname(addr); if (he == NULL) { pthread_mutex_unlock (&mymutex); // add by qfdai2 anetSetError(err, "can't resolve: %s\n", addr); close(s); return ANET_ERR; } memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); pthread_mutex_unlock (&mymutex); // add by qfdai2 } if (flags & ANET_CONNECT_NONBLOCK) { if (anetNonBlock(err,s) != ANET_OK) return ANET_ERR; } if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) return s; anetSetError(err, "connect: %s\n", strerror(errno)); close(s); return ANET_ERR; } return s; }
ugClient *createClient(int fd) { ugClient *c = zmalloc(sizeof(ugClient)); memset(c,0,sizeof(ugClient)); if (fd != -1) { anetNonBlock(NULL,fd); anetEnableTcpNoDelay(NULL,fd); if (server.tcpkeepalive) anetKeepAlive(NULL, fd, server.tcpkeepalive); if (aeCreateFileEvent(server.el, fd, AE_READABLE, readQueryFromClient, c) == AE_ERR) { #ifdef _WIN32 aeWinCloseSocket(fd); #else close(fd); #endif zfree(c); return NULL; } } if (server.config->password == NULL) { c->authenticated = 1; } c->querybuf = sdsempty(); c->fd = fd; c->ctime = c->lastinteraction = time(NULL); c->multibulklen = 0; c->bulklen = -1; c->reply = listCreate(); c->reply_bytes = 0; c->bufpos = 0; c->sentlen = 0; /* listSetDupMethod(c->reply, listDupReplyObjects); */ listSetFreeMethod(c->reply, listFreeReplyObjects); c->pubsub_channels = dictCreate(&callbackDict, NULL); c->pubsub_patterns = listCreate(); listSetMatchMethod(c->pubsub_patterns, listMatchPubsubPattern); listSetFreeMethod(c->pubsub_patterns, listFreePubsubPattern); /* c->pubsub_patterns = listCreate(); */ if (!server.clients) { server.clients = createClientlist(); } listAddNodeTail(server.clients, c); return c; }
int easysocketbenchmark::createclient(){ int fd = anetTcpConnect(NULL, this->ip, this->port); while(ANET_ERR == fd){ fd = anetTcpConnect(NULL, this->ip, this->port); } /*if( ANET_ERR == fd ){ //fprintf(stderr, "connect error: %s\n", PORT, NULL); printf("connect error......"); }*/ if(anetNonBlock(NULL, fd) == ANET_ERR){ //fprintf(stderr, "set nonblock error: %d\n", fd); //printf("set nonblock error......"); } return fd; }
static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) { int s; struct sockaddr_in sa; unsigned long inAddress; if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR) return ANET_ERR; sa.sin_family = AF_INET; sa.sin_port = htons((u_short)port); inAddress = inet_addr(addr); if (inAddress == INADDR_NONE || inAddress == INADDR_ANY) { struct hostent *he; he = gethostbyname(addr); if (he == NULL) { anetSetError(err, "can't resolve: %s\n", addr); closesocket(s); return ANET_ERR; } memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); } else { sa.sin_addr.s_addr = inAddress; } if (flags & ANET_CONNECT_NONBLOCK) { if (anetNonBlock(err,s) != ANET_OK) return ANET_ERR; } if (connect((SOCKET)s, (struct sockaddr*)&sa, sizeof(sa)) == SOCKET_ERROR) { errno = WSAGetLastError(); if ((errno == WSAEWOULDBLOCK)) errno = EINPROGRESS; if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) { aeWinSocketAttach(s); return s; } anetSetError(err, "connect: %d\n", errno); closesocket(s); return ANET_ERR; } if (flags & ANET_CONNECT_NONBLOCK) { aeWinSocketAttach(s); } return s; }
void modesInitNet(void) { int j; struct service svc[MODES_NET_SERVICES_NUM] = { {"Raw TCP output", &Modes.ros, Modes.net_output_raw_port, 1}, {"Raw TCP input", &Modes.ris, Modes.net_input_raw_port, 1}, {"Beast TCP output", &Modes.bos, Modes.net_output_beast_port, 1}, {"Beast TCP input", &Modes.bis, Modes.net_input_beast_port, 1}, {"HTTP server", &Modes.https, Modes.net_http_port, 1}, {"Basestation TCP output", &Modes.sbsos, Modes.net_output_sbs_port, 1} }; memcpy(&services, &svc, sizeof(svc));//services = svc; Modes.clients = NULL; #ifdef _WIN32 if ( (!Modes.wsaData.wVersion) && (!Modes.wsaData.wHighVersion) ) { // Try to start the windows socket support if (WSAStartup(MAKEWORD(2,1),&Modes.wsaData) != 0) { fprintf(stderr, "WSAStartup returned Error\n"); } } #endif for (j = 0; j < MODES_NET_SERVICES_NUM; j++) { services[j].enabled = (services[j].port != 0); if (services[j].enabled) { int s = anetTcpServer(Modes.aneterr, services[j].port, Modes.net_bind_address); if (s == -1) { fprintf(stderr, "Error opening the listening port %d (%s): %s\n", services[j].port, services[j].descr, Modes.aneterr); exit(1); } anetNonBlock(Modes.aneterr, s); *services[j].socket = s; } else { if (Modes.debug & MODES_DEBUG_NET) printf("%s port is disabled\n", services[j].descr); } } #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); #endif }
vuiClient * createClient(int fd) { if (server.client != NULL) { close(fd); return NULL; } LogInfo("creat client fd:%d", fd); vuiClient *c = zmalloc(sizeof(vuiClient)); memset(c, 0, sizeof(vuiClient)); c->querybuf = sdsempty(); c->querymsg = sdsempty(); c->prot.method = NULL; c->prot.version = NULL; c->prot.body = NULL; c->prot.lenght = 0; c->prot.waiting = 0; c->res.version = "VPC/1.0"; c->res.code = 200; c->res.reason = sdsnew("OK"); c->res.body = sdsempty(); c->res.buf = sdsempty(); c->jsons = listCreate(); c->fd = fd; anetNonBlock(NULL,fd); anetEnableTcpNoDelay(NULL,fd); if (aeCreateFileEvent(server.el, fd, AE_READABLE, readQueryFromClient, c) == AE_ERR) { close(fd); zfree(c); return NULL; } server.client = c; return c; }
static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) { int s, rv; char _port[6]; /* strlen("65535"); */ struct addrinfo hints, *servinfo, *p; snprintf(_port,6,"%d",port); memset(&hints,0,sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { anetSetError(err, "%s", gai_strerror(rv)); return ANET_ERR; } for (p = servinfo; p != NULL; p = p->ai_next) { if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) continue; /* if we set err then goto cleanup, otherwise next */ if (anetSetReuseAddr(err,s) == ANET_ERR) goto error; if (flags & ANET_CONNECT_NONBLOCK && anetNonBlock(err,s) != ANET_OK) goto error; if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) goto end; close(s); continue; } /* break with the socket */ goto end; } if (p == NULL) { anetSetError(err, "creating socket: %s", strerror(errno)); goto error; } error: s = ANET_ERR; end: freeaddrinfo(servinfo); return s; }
//接受新连接 void AcceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask){ int cfd, cport; char ip_addr[128] = { 0 }; cfd = anetTcpAccept(g_err_string, fd, ip_addr, strlen(ip_addr), &cport); printf("Connected from %s:%d\n", ip_addr, cport); if(anetNonBlock(g_err_string, cfd) == ANET_ERR){ fprintf(stderr, "set nonblock error: %d\n", fd); } if(anetEnableTcpNoDelay(g_err_string,fd) == ANET_ERR){ fprintf(stderr, "set nodelay error: %d\n", fd); } if( aeCreateFileEvent(el, cfd, AE_READABLE, ReadFromClient, NULL) == AE_ERR ){ fprintf(stderr, "client connect fail: %d\n", fd); close(fd); } }
testclient* createClient(int fd) { testclient* c = zmalloc(sizeof(testclient)); if (fd != -1) { anetNonBlock(NULL, fd); anetEnableTcpNoDelay(NULL, fd); if (server.tcpkeepalive) anetKeepAlive(NULL, fd, server.tcpkeepalive); if (aeCreateFileEvent(server.el, fd, AE_READABLE, readRequestFromClient, c) == AE_ERR) { close(fd); zfree(c); return NULL; } } c->cfd = fd; c->requestbuf = sdsempty(); if (fd != -1) listAddNodeTail(server.clients, c); return c; }
//这里的信号是终端执行的中断等操作引起的事件。 //所以此处的addEvent是加入到主进程event_loop中的。 void installMasterSignal( aeServer* serv ) { int ret; char neterr[1024]; //这个管道不是与worker通信的,而是与主线程的自己通信的 ret = socketpair( PF_UNIX, SOCK_STREAM, 0, serv->sigPipefd ); assert( ret != -1 ); anetNonBlock( neterr, serv->sigPipefd[1] ); //把信号管道一端加到master event_loop中,使其被epoll关注 ret = aeCreateFileEvent( serv->mainReactor->eventLoop , serv->sigPipefd[0],AE_READABLE,onSignEvent,NULL); //装载信号,指定回调函数,如果用户引发信号事件,则回调。 addSignal( SIGCHLD, masterSignalHandler , 1 ); //catch child process exit event //addSignal( SIGTERM, masterSignalHandler , 1 ); //catch exit event by kill or Ctrl+C .. addSignal( SIGINT, masterSignalHandler , 1 ); addSignal( SIGPIPE, SIG_IGN , 1 ); }
proxy_client*AllocRemote(proxy_client*c) { proxy_client*r=malloc(sizeof(proxy_client)); r->flags=0; int fd=anetTcpNonBlockConnect(anet_error,policy->hosts[0].addr,policy->hosts[0].port); if(r==NULL||fd==-1) return NULL; LogDebug("connect remote fd:%d",fd); anetNonBlock(NULL,fd); anetTcpNoDelay(NULL,fd); r->fd=fd; r->remote=c; r->OnError=RemoteDown; r->blist=AllocBufferList(3); if(aeCreateFileEvent(el,r->fd,AE_READABLE,ReadIncome,r)==AE_ERR){ //bug:free remote close(fd); return NULL; } LogDebug("new peer:%d---%d",r->fd,c->fd); return r; }