/* * Create a loopback socket and set it up to listen on the specified * port. Return the new socket or INVALID_SOCKET if there's an error. */ SOCKET sysCreateServerSocket(int port) { SOCKET server; SOCKADDR_IN iname = {0}; int length = sizeof(iname); sysInitSocketLibrary(); iname.sin_family = AF_INET; iname.sin_port = htons((u_short)port); iname.sin_addr.s_addr = inet_addr("127.0.0.1"); if ((server = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { return INVALID_SOCKET; } if (bind(server, (SOCKADDR *)&iname, sizeof(iname)) == SOCKET_ERROR) { sysCloseSocket(server); return INVALID_SOCKET; } if (listen(server, SOMAXCONN) == SOCKET_ERROR) { sysCloseSocket(server); return INVALID_SOCKET; } return server; }
/* * Tests creatability of a loopback socket for the specified port. * If the test fails, INVALID_SOCKET is returned, otherwise the * would-be socket is returned. For the special case *port == 0, * the port will be reset to an ephemeral port (chosen by the kernel). */ SOCKET sysTestServerSocketCreatable(int* port) { SOCKET sock; SOCKADDR_IN iname = {0}; int length = sizeof(iname); sysInitSocketLibrary(); iname.sin_family = AF_INET; iname.sin_port = htons((u_short)*port); iname.sin_addr.s_addr = inet_addr("127.0.0.1"); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { return INVALID_SOCKET; } /* When bind() is called and *port==0, kernel will choose ephemeral port */ if (bind(sock, (SOCKADDR *)&iname, sizeof(iname)) == SOCKET_ERROR) { sysCloseSocket(sock); return INVALID_SOCKET; } /* When getsockname() is called, iname is updated to reflect port used by kernel */ if (getsockname(sock, (SOCKADDR *)&iname, &length) == SOCKET_ERROR) { sysCloseSocket(sock); return INVALID_SOCKET; } /* At this juncture, we have a valid socket and a valid (possibly ephemeral) port */ *port = ntohs(iname.sin_port); sysCloseSocket(sock); return sock; }
/* * Safely close a socket. The following note comes from socket_md.c * which is in src/win32/hpi/src/ in the JDK sources. * * Generally speaking, it is important to shutdown a socket before * closing it, since failing to do so can sometimes result in a TCP * RST (abortive close) which is disturbing to the peer of the * connection. * * The Winsock way to shutdown a socket is the Berkeley call * shutdown(). We do not want to call it on Win95, since it * sporadically leads to an OS crash in IFS_MGR.VXD. Complete hull * breach. Blue screen. Ugly. * * So we use the WSASendDisconnect function if it was found at initialization * time, before calling closesocket. */ void sysCloseSocket(SOCKET s) { sysInitSocketLibrary(); if (s <= 0) { return; } if (sendDisconnect) { sendDisconnect(s, NULL); /* WSASendDisconnect */ } closesocket(s); }
/* * Create a loopback socket connected to the specified port. Return the * new socket or INVALID_SOCKET if there's an error. */ SOCKET sysCreateClientSocket(int port) { SOCKET client; SOCKADDR_IN iname = {0}; sysInitSocketLibrary(); iname.sin_family = AF_INET; iname.sin_port = htons((u_short)port); iname.sin_addr.s_addr = inet_addr("127.0.0.1"); if ((client = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { return INVALID_SOCKET; } if (connect(client, (SOCKADDR *)&iname, sizeof(iname)) == SOCKET_ERROR) { sysCloseSocket(client); return INVALID_SOCKET; } return client; }