int socket_bind(const char * ip, int port, int protocol) { int s; #ifdef __WIN32 SOCKADDR_IN sa; #else struct sockaddr_in sa; #endif if ((s = socket(AF_INET, protocol, 0)) < 0) { sys_err("socket: %s", strerror(errno)); return -1; } socket_reuse(s); #ifndef __WIN32__ socket_lingeroff(s); #else // Winsock2: SO_DONTLINGER, SO_KEEPALIVE, SO_LINGER, and SO_OOBINLINE are // not supported on sockets of type SOCK_DGRAM if (protocol == SOCK_STREAM) { socket_lingeroff(s); } #endif memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; //윈도우 서버는 개발용으로만 쓰기 때문에 BIND ip를 INADDR_ANY로 고정 //(테스트의 편의성을 위해) #ifndef __WIN32__ sa.sin_addr.s_addr = inet_addr(ip); #else sa.sin_addr.s_addr = INADDR_ANY; #endif sa.sin_port = htons((unsigned short) port); if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) { sys_err("bind: %s", strerror(errno)); return -1; } socket_nonblock(s); if (protocol == SOCK_STREAM) { sys_log(0, "SYSTEM: BINDING TCP PORT ON [%d] (fd %d)", port, s); listen(s, SOMAXCONN); } else sys_log(0, "SYSTEM: BINDING UDP PORT ON [%d] (fd %d)", port, s); return s; }
void mainloop(int sock) { char code; int newsock; iopoll_fd fds; fds.fd = sock; fds.events = IOPOLL_READ; for (;;) { switch (iopoll_restart(&fds, 1, timeout*1000)) { case -1: return; case 0: /* Timed out */ if (kill(ppid, 0) == -1) return; continue; default: if (read(sock, &code, 1) != 1) return; code = 0; if ((newsock = socket_tcp()) == -1) { error1sys("Creating socket failed"); code = 1; } else if (!socket_reuse(newsock)) { error1sys("Setting flags on socket failed"); code = 2; } else if (!socket_bind4(newsock, &ip, port)) { error1sys("Binding socket failed"); code = 3; } if (write(sock, &code, 1) != 1) error1sys("Sending the result code failed"); if (!code) if (!socket_sendfd(sock, newsock)) error1sys("Sending the bound socket failed"); close(newsock); } } }