void netserver_tick(NetServer *s) { int i; int n; if(!s) return; if(s->listen_sock != INVALID_SOCKET) { SOCKET as; struct sockaddr client_address = {0}; while((as = socket_accept(&s->listen_sock, &client_address)) != INVALID_SOCKET) { NetLink *l = NetLink_Create(s->ctxt); SOCK_CLEAR_DELAY(as); sock_set_noblocking(as); l->sock = as; l->address = client_address; l->s = s; *alnk_push(&s->clients) = l; } } n = alnk_size(&s->clients); for( i = n - 1; i >= 0; --i ) { NetLink *c = s->clients[i]; if(!netlink_tick(c)) { NetLink_Destroy(&c); alnk_rm(&s->clients,i,1); } } }
NetLink* net_connect(NetCtxt *ctxt, char *addr, U16 port, LinkConnFp conn_callback, LinkDiscoFp disco_callback, MessageFp msg_callback, BOOL block) { NetLink *c; char port_str[32]; struct addrinfo *aiList = NULL; struct addrinfo aiHints = {0}; if(!addr) return NULL; aiHints.ai_family = AF_INET; aiHints.ai_socktype = SOCK_STREAM; aiHints.ai_protocol = IPPROTO_TCP; itoa(port,port_str,10); if(0!=getaddrinfo(IPADDR(addr), port_str, &aiHints, &aiList)) return NULL; c = NetLink_Create(ctxt); c->conn_callback = conn_callback; c->disco_callback = disco_callback; c->msg_callback = msg_callback; c->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(!block) sock_set_noblocking(c->sock); if(connect(c->sock, aiList->ai_addr, (int)aiList->ai_addrlen) == 0) c->connected = TRUE; else if(block || last_error() != EWOULDBLOCK) { LOG("failed to connect to %s server",addr); NetLink_Destroy(&c); freeaddrinfo(aiList); return NULL; } freeaddrinfo(aiList); sock_set_noblocking(c->sock); *alnk_push(&ctxt->links) = c; return c; }
void fd_open(int fd, int type) { assert(fd_table); struct fd_t *f = &fd_table[fd]; f->fd = fd; f->flags.open = 1; f->type = type; f->wqueue = NULL; if(fd > biggest_fd) biggest_fd = fd; sock_set_noblocking(fd); sock_set_cork(fd); }
NetServer* netserver_create(NetCtxt *ctxt, U16 port, LinkConnFp conn_callback, LinkDiscoFp disco_callback, MessageFp msg_callback) { struct sockaddr_in service = {0}; // bind NetServer *s = NetServer_Create(ctxt); s->port = port; s->listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); s->conn_callback = conn_callback; s->disco_callback = disco_callback; s->msg_callback = msg_callback; if(s->listen_sock == INVALID_SOCKET) { printf("error creating socket %s\n", last_error_str()); goto error; } if(!sock_set_noblocking(s->listen_sock)) { printf("error setting listen socket to async: %s\n", last_error_str()); goto error; } service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr("127.0.0.1"); service.sin_port = htons(port); if(bind( s->listen_sock, (SOCKADDR*)&service,sizeof(service)) == SOCKET_ERROR) { printf("bind failed %s\n",last_error_str()); goto error; } SOCK_CLEAR_DELAY(s->listen_sock); if(listen(s->listen_sock,1) == SOCKET_ERROR) { printf("listen failed %s\n",last_error_str()); goto error; } return s; error: NetServer_Destroy(&s); return NULL; }