module ServerEngine::SocketManagerWin::ServerModule
Constants
- TCP_OPTIONS
- UDP_OPTIONS
Private Instance Methods
htons(h)
click to toggle source
# File lib/serverengine/socket_manager_win.rb, line 106 def htons(h) [h].pack("S").unpack("n")[0] end
listen_new(proto, bind_ip, port)
click to toggle source
# File lib/serverengine/socket_manager_win.rb, line 66 def listen_new(proto, bind_ip, port) protocol, proto_info, klass, listen = case proto when :tcp then TCP_OPTIONS when :udp then UDP_OPTIONS else raise ArgumentError, "invalid protocol: #{proto}" end family = bind_ip.ipv6? ? Socket::AF_INET6 : Socket::AF_INET sock_addr = Socket.pack_sockaddr_in(port, bind_ip.to_s) handle = WinSock.WSASocketA(family, protocol, proto_info, nil, 0, 1) if handle == WinSock::INVALID_SOCKET RbWinSock.raise_last_error("WSASocketA(2)") end # wrap in TCPServer/UDPSocket immediately so that its finalizer safely closes the handle sock = RbWinSock.wrap_io_handle(klass, handle, 0) unless WinSock.bind(sock.handle, sock_addr, sock_addr.bytesize) == 0 RbWinSock.raise_last_error("bind(2)") end if listen unless WinSock.listen(sock.handle, Socket::SOMAXCONN) == 0 RbWinSock.raise_last_error("listen(2)") end end sock end
listen_tcp_new(bind_ip, port)
click to toggle source
# File lib/serverengine/socket_manager_win.rb, line 98 def listen_tcp_new(bind_ip, port) listen_new(:tcp, bind_ip, port) end
listen_udp_new(bind_ip, port)
click to toggle source
# File lib/serverengine/socket_manager_win.rb, line 102 def listen_udp_new(bind_ip, port) listen_new(:udp, bind_ip, port) end
send_socket(peer, pid, method, bind, port)
click to toggle source
# File lib/serverengine/socket_manager_win.rb, line 136 def send_socket(peer, pid, method, bind, port) case method when :listen_tcp sock = listen_tcp(bind, port) type = Socket::SOCK_STREAM when :listen_udp sock = listen_udp(bind, port) type = Socket::SOCK_DGRAM else raise ArgumentError, "Unknown method: #{method.inspect}" end proto = WinSock::WSAPROTOCOL_INFO.malloc unless WinSock.WSADuplicateSocketA(sock.handle, pid, proto) == 0 RbWinSock.raise_last_error("WSADuplicateSocketA(3)") end SocketManager.send_peer(peer, proto.to_bin) end
start_server(addr)
click to toggle source
# File lib/serverengine/socket_manager_win.rb, line 110 def start_server(addr) # TODO: use TCPServer, but this is risky because using not conflict path is easy, # but using not conflict port is difficult. Then We had better implement using NamedPipe. @server = TCPServer.new("127.0.0.1", addr) @thread = Thread.new do begin while peer = @server.accept Thread.new(peer, &method(:process_peer)) # process_peer calls send_socket end rescue => e unless @server.closed? ServerEngine.dump_uncaught_error(e) end end end return path end
stop_server()
click to toggle source
# File lib/serverengine/socket_manager_win.rb, line 129 def stop_server @tcp_sockets.reject! {|key,lsock| lsock.close; true } @udp_sockets.reject! {|key,usock| usock.close; true } @server.close unless @server.closed? @thread.join end