コード例 #1
0
ファイル: sun.nio.ch.cs プロジェクト: cDoru/ikvm-fork
    public static int connect0(FileDescriptor fd, bool preferIPv6, InetAddress remote, int remotePort, object handler)
    {
#if FIRST_PASS
        return(0);
#else
        return(new Connect().Do(fd.getSocket(), new System.Net.IPEndPoint(java.net.SocketUtil.getAddressFromInetAddress(remote, preferIPv6), remotePort), handler));
#endif
    }
コード例 #2
0
ファイル: sun.nio.ch.cs プロジェクト: cDoru/ikvm-fork
    public static int write0(FileDescriptor fd, ByteBuffer[] bufs, object handler)
    {
#if FIRST_PASS
        return(0);
#else
        return(new Send().Do(fd.getSocket(), bufs, handler));
#endif
    }
コード例 #3
0
ファイル: sun.nio.ch.cs プロジェクト: cDoru/ikvm-fork
    public static int accept0(FileDescriptor listenSocket, FileDescriptor acceptSocket, object handler)
    {
#if FIRST_PASS
        return(0);
#else
        return(new Accept().Do(listenSocket.getSocket(), acceptSocket.getSocket(), handler));
#endif
    }
コード例 #4
0
ファイル: sun.nio.ch.cs プロジェクト: cDoru/ikvm-fork
    public static void disconnect0(FileDescriptor fd, bool isIPv6)
    {
#if !FIRST_PASS
        try
        {
            fd.getSocket().Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0));
            IKVM.NativeCode.sun.nio.ch.Net.setConnectionReset(fd.getSocket(), false);
        }
        catch (System.Net.Sockets.SocketException x)
        {
            throw java.net.SocketUtil.convertSocketExceptionToIOException(x);
        }
        catch (ObjectDisposedException)
        {
            throw new java.net.SocketException("Socket is closed");
        }
#endif
    }
コード例 #5
0
ファイル: sun.nio.ch.cs プロジェクト: cDoru/ikvm-fork
    public static int send0(object obj, bool preferIPv6, FileDescriptor fd, byte[] buf, int pos, int len, InetAddress addr, int port)
    {
#if FIRST_PASS
        return(0);
#else
        try
        {
            return(fd.getSocket().SendTo(buf, pos, len, System.Net.Sockets.SocketFlags.None, new System.Net.IPEndPoint(java.net.SocketUtil.getAddressFromInetAddress(addr, preferIPv6), port)));
        }
        catch (System.Net.Sockets.SocketException x)
        {
            if (x.ErrorCode == java.net.SocketUtil.WSAEWOULDBLOCK)
            {
                return(sun.nio.ch.IOStatus.UNAVAILABLE);
            }
            throw java.net.SocketUtil.convertSocketExceptionToIOException(x);
        }
        catch (ObjectDisposedException)
        {
            throw new java.net.SocketException("Socket is closed");
        }
#endif
    }
コード例 #6
0
ファイル: sun.nio.ch.cs プロジェクト: cDoru/ikvm-fork
    public static int receive0(object obj, FileDescriptor fd, byte[] buf, int pos, int len, bool connected)
    {
#if FIRST_PASS
        return(0);
#else
        sun.nio.ch.DatagramChannelImpl impl          = (sun.nio.ch.DatagramChannelImpl)obj;
        java.net.SocketAddress         remoteAddress = impl.remoteAddress();
        System.Net.EndPoint            remoteEP;
        if (fd.getSocket().AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
        {
            remoteEP = new System.Net.IPEndPoint(System.Net.IPAddress.IPv6Any, 0);
        }
        else
        {
            remoteEP = new System.Net.IPEndPoint(0, 0);
        }
        java.net.InetSocketAddress addr;
        int length;
        do
        {
            for (; ;)
            {
                try
                {
                    length = fd.getSocket().ReceiveFrom(buf, pos, len, System.Net.Sockets.SocketFlags.None, ref remoteEP);
                    break;
                }
                catch (System.Net.Sockets.SocketException x)
                {
                    if (x.ErrorCode == java.net.SocketUtil.WSAECONNRESET)
                    {
                        // A previous send failed (i.e. the remote host responded with a ICMP that the port is closed) and
                        // the winsock stack helpfully lets us know this, but we only care about this when we're connected,
                        // otherwise we'll simply retry the receive (note that we use SIO_UDP_CONNRESET to prevent these
                        // WSAECONNRESET exceptions, but when switching from connected to disconnected, some can slip through).
                        if (connected)
                        {
                            throw new java.net.PortUnreachableException();
                        }
                        continue;
                    }
                    if (x.ErrorCode == java.net.SocketUtil.WSAEMSGSIZE)
                    {
                        // The buffer size was too small for the packet, ReceiveFrom receives the part of the packet
                        // that fits in the buffer and then throws an exception, so we have to ignore the exception in this case.
                        length = len;
                        break;
                    }
                    if (x.ErrorCode == java.net.SocketUtil.WSAEWOULDBLOCK)
                    {
                        return(sun.nio.ch.IOStatus.UNAVAILABLE);
                    }
                    throw java.net.SocketUtil.convertSocketExceptionToIOException(x);
                }
                catch (ObjectDisposedException)
                {
                    throw new java.net.SocketException("Socket is closed");
                }
            }
            System.Net.IPEndPoint ep = (System.Net.IPEndPoint)remoteEP;
            addr = new java.net.InetSocketAddress(java.net.SocketUtil.getInetAddressFromIPEndPoint(ep), ep.Port);
        } while (remoteAddress != null && !addr.equals(remoteAddress));
        impl.sender = addr;
        return(length);
#endif
    }
コード例 #7
0
    public static int socketRead0(object _this, java.io.FileDescriptor fd, byte[] b, int off, int len, int timeout)
    {
#if FIRST_PASS
        return(0);
#else
        // [IKVM] this method is a direct port of the native code in openjdk6-b18\jdk\src\windows\native\java\net\SocketInputStream.c
        System.Net.Sockets.Socket socket = null;
        int nread;

        if (fd == null)
        {
            throw new SocketException("socket closed");
        }
        socket = fd.getSocket();
        if (socket == null)
        {
            throw new SocketException("Socket closed");
        }

        if (timeout != 0)
        {
            if (timeout <= 5000 || !net_util_md.isRcvTimeoutSupported)
            {
                int ret = net_util_md.NET_Timeout(socket, timeout);

                if (ret <= 0)
                {
                    if (ret == 0)
                    {
                        throw new SocketTimeoutException("Read timed out");
                    }
                    else
                    {
                        // [IKVM] the OpenJDK native code is broken and always throws this exception on any failure of NET_Timeout
                        throw new SocketException("socket closed");
                    }
                }

                /*check if the socket has been closed while we were in timeout*/
                if (fd.getSocket() == null)
                {
                    throw new SocketException("Socket Closed");
                }
            }
        }

        nread = Winsock.recv(socket, b, off, len, 0);
        if (nread > 0)
        {
            // ok
        }
        else
        {
            if (nread < 0)
            {
                /*
                 * Recv failed.
                 */
                switch (Winsock.WSAGetLastError())
                {
                case Winsock.WSAEINTR:
                    throw new SocketException("socket closed");

                case Winsock.WSAECONNRESET:
                case Winsock.WSAESHUTDOWN:
                    /*
                     * Connection has been reset - Windows sometimes reports
                     * the reset as a shutdown error.
                     */
                    throw new sun.net.ConnectionResetException();

                case Winsock.WSAETIMEDOUT:
                    throw new SocketTimeoutException("Read timed out");

                default:
                    throw net_util_md.NET_ThrowCurrent("recv failed");
                }
            }
        }
        return(nread);
#endif
    }
コード例 #8
0
    public static void socketWrite0(object _this, java.io.FileDescriptor fd, byte[] data, int off, int len)
    {
#if !FIRST_PASS
        // [IKVM] this method is a direct port of the native code in openjdk6-b18\jdk\src\windows\native\java\net\SocketOutputStream.c
        const int MAX_BUFFER_LEN = 2048;
        System.Net.Sockets.Socket socket;
        int buflen = 65536;         // MAX_HEAP_BUFFER_LEN
        int n;

        if (fd == null)
        {
            throw new SocketException("socket closed");
        }
        else
        {
            socket = fd.getSocket();
        }
        if (data == null)
        {
            throw new java.lang.NullPointerException("data argument");
        }

        while (len > 0)
        {
            int loff     = 0;
            int chunkLen = java.lang.Math.min(buflen, len);
            int llen     = chunkLen;
            int retry    = 0;

            while (llen > 0)
            {
                n = Winsock.send(socket, data, off + loff, llen, 0);
                if (n > 0)
                {
                    llen -= n;
                    loff += n;
                    continue;
                }

                /*
                 * Due to a bug in Windows Sockets (observed on NT and Windows
                 * 2000) it may be necessary to retry the send. The issue is that
                 * on blocking sockets send/WSASend is supposed to block if there
                 * is insufficient buffer space available. If there are a large
                 * number of threads blocked on write due to congestion then it's
                 * possile to hit the NT/2000 bug whereby send returns WSAENOBUFS.
                 * The workaround we use is to retry the send. If we have a
                 * large buffer to send (>2k) then we retry with a maximum of
                 * 2k buffer. If we hit the issue with <=2k buffer then we backoff
                 * for 1 second and retry again. We repeat this up to a reasonable
                 * limit before bailing out and throwing an exception. In load
                 * conditions we've observed that the send will succeed after 2-3
                 * attempts but this depends on network buffers associated with
                 * other sockets draining.
                 */
                if (Winsock.WSAGetLastError() == Winsock.WSAENOBUFS)
                {
                    if (llen > MAX_BUFFER_LEN)
                    {
                        buflen   = MAX_BUFFER_LEN;
                        chunkLen = MAX_BUFFER_LEN;
                        llen     = MAX_BUFFER_LEN;
                        continue;
                    }
                    if (retry >= 30)
                    {
                        throw new SocketException("No buffer space available - exhausted attempts to queue buffer");
                    }
                    System.Threading.Thread.Sleep(1000);
                    retry++;
                    continue;
                }

                /*
                 * Send failed - can be caused by close or write error.
                 */
                if (Winsock.WSAGetLastError() == Winsock.WSAENOTSOCK)
                {
                    throw new SocketException("Socket closed");
                }
                else
                {
                    throw net_util_md.NET_ThrowCurrent("socket write error");
                }
            }
            len -= chunkLen;
            off += chunkLen;
        }
#endif
    }