2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 // Address length was changed from long to int for performance reasons.
20 // Harmony implements INetworkSystem's methods with native methods; Android
21 // implements them with Java that call through to native wrappers.
22 // TODO: change the native code to eliminate the wrappers
25 package org.apache.harmony.luni.platform;
27 import java.io.FileDescriptor;
28 import java.io.IOException;
29 import java.net.DatagramPacket;
30 import java.net.InetAddress;
31 import java.net.SocketException;
32 import java.net.SocketImpl;
33 import java.net.UnknownHostException;
34 import java.nio.channels.Channel;
35 // BEGIN android-removed
36 // import java.nio.channels.SelectableChannel;
37 // END android-removed
40 * This wraps native code that implements the INetworkSystem interface.
42 final class OSNetworkSystem implements INetworkSystem {
44 private static final int ERRORCODE_SOCKET_TIMEOUT = -209;
45 private static final int ERRORCODE_SOCKET_INTERRUPTED = -208;
47 private static final int INETADDR_REACHABLE = 0;
49 private static boolean isNetworkInited = false;
51 private static OSNetworkSystem singleton = new OSNetworkSystem();
54 * Answers the unique instance of the OSNetworkSystem.
56 * @return the network system interface instance
58 public static OSNetworkSystem getOSNetworkSystem() {
62 // Can not be instantiated.
63 private OSNetworkSystem() {
67 public void accept(FileDescriptor fdServer, SocketImpl newSocket,
68 FileDescriptor fdnewSocket, int timeout) throws IOException {
69 acceptSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
72 static native void acceptSocketImpl(FileDescriptor fdServer,
73 SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
76 // BEGIN android-removed
77 // public void acceptStreamSocket(FileDescriptor fdServer,
78 // SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
79 // throws IOException {
80 // acceptStreamSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
83 // static native void acceptStreamSocketImpl(FileDescriptor fdServer,
84 // SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
85 // throws IOException;
86 // END android-removed
88 public int availableStream(FileDescriptor fd) throws SocketException {
89 return availableStreamImpl(fd);
92 static native int availableStreamImpl(FileDescriptor aFD) throws SocketException;
95 * Associates a local address with a socket.
98 * the socket descriptor
103 * @throws SocketException
104 * thrown if bind operation fails
106 public void bind(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException {
107 socketBindImpl(fd, port, inetAddress);
110 static native void socketBindImpl(FileDescriptor aFD, int port, InetAddress inetAddress) throws SocketException;
112 public int connect(FileDescriptor fd, int trafficClass,
113 InetAddress inetAddress, int port) throws IOException{
114 return connectSocketImpl(fd, trafficClass, inetAddress, port);
117 static native int connectSocketImpl(FileDescriptor aFD,
118 int trafficClass, InetAddress inetAddress, int port);
120 public void connectDatagram(FileDescriptor fd, int port,
121 int trafficClass, InetAddress inetAddress) throws SocketException {
122 connectDatagramImpl2(fd, port, trafficClass, inetAddress);
125 static native void connectDatagramImpl2(FileDescriptor aFD, int port,
126 int trafficClass, InetAddress inetAddress) throws SocketException;
128 public void connectStreamWithTimeoutSocket(FileDescriptor aFD,
129 int aport, int timeout, int trafficClass, InetAddress inetAddress)
131 connectStreamWithTimeoutSocketImpl(aFD, aport, timeout, trafficClass,
135 static native void connectStreamWithTimeoutSocketImpl(FileDescriptor aFD,
136 int aport, int timeout, int trafficClass, InetAddress inetAddress)
139 // BEGIN android-changed
140 // changed context from Long to byte[]
141 public int connectWithTimeout(FileDescriptor fd, int timeout,
142 int trafficClass, InetAddress inetAddress, int port, int step,
143 byte[] context) throws IOException {
144 return connectWithTimeoutSocketImpl(fd, timeout, trafficClass,
145 inetAddress, port, step, context);
148 static native int connectWithTimeoutSocketImpl(FileDescriptor aFD,
149 int timeout, int trafficClass, InetAddress hostname, int port, int step,
151 // END android-changed
153 public void createDatagramSocket(FileDescriptor fd,
154 boolean preferIPv4Stack) throws SocketException {
155 createDatagramSocketImpl(fd, preferIPv4Stack);
159 * Allocate a datagram socket in the IP stack. The socket is associated with
160 * the <code>aFD</code>.
162 * @param aFD the FileDescriptor to associate with the socket @param
163 * preferIPv4Stack IP stack preference if underlying platform is V4/V6
164 * @exception SocketException upon an allocation error
166 static native void createDatagramSocketImpl(FileDescriptor aFD,
167 boolean preferIPv4Stack) throws SocketException;
169 public void createServerStreamSocket(FileDescriptor fd,
170 boolean preferIPv4Stack) throws SocketException {
171 createServerStreamSocketImpl(fd, preferIPv4Stack);
175 * Answer the result of attempting to create a server stream socket in the
176 * IP stack. Any special options required for server sockets will be set by
179 * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
180 * @exception SocketException if an error occurs while creating the socket
182 static native void createServerStreamSocketImpl(FileDescriptor aFD,
183 boolean preferIPv4Stack) throws SocketException;
185 public void createStreamSocket(FileDescriptor fd,
186 boolean preferIPv4Stack) throws SocketException {
187 createStreamSocketImpl(fd, preferIPv4Stack);
190 static native void createStreamSocketImpl(FileDescriptor aFD,
191 boolean preferIPv4Stack) throws SocketException;
194 * Disconnect the socket to a port and address
197 * the FileDescriptor associated with the socket
199 * @throws SocketException
200 * if the disconnect fails
202 public void disconnectDatagram(FileDescriptor fd)
203 throws SocketException {
204 disconnectDatagramImpl(fd);
207 static native void disconnectDatagramImpl(FileDescriptor aFD)
208 throws SocketException;
210 public InetAddress getHostByAddr(byte[] ipAddress)
211 throws UnknownHostException {
212 // BEGIN android-changed
213 // Wallpaper fix for http://b/1851257. This is a layering violation,
214 // but at least the method has the right return type.
215 // TODO: Fix the socket code to remove this method altogether.
216 return InetAddress.getByAddress(ipAddress);
217 // END android-changed
219 // BEGIN android-removed
220 // static native InetAddress getHostByAddrImpl(byte[] addr)
221 // throws UnknownHostException;
222 // END android-removed
224 // BEGIN android-removed
225 public InetAddress getHostByName(String hostName,
226 boolean preferIPv6Addresses) throws UnknownHostException {
227 // BEGIN android-changed
228 // Wallpaper fix for http://b/1851257.
229 return InetAddress.getByName(hostName);
230 // END android-changed
233 // BEGIN android-removed
234 // static native InetAddress getHostByNameImpl(String addr,
235 // boolean preferIPv6Addresses) throws UnknownHostException;
236 // END android-removed
238 public int getSocketFlags() {
239 return getSocketFlagsImpl();
242 static native int getSocketFlagsImpl();
244 public InetAddress getSocketLocalAddress(FileDescriptor fd,
245 boolean preferIPv6Addresses) {
246 return getSocketLocalAddressImpl(fd, preferIPv6Addresses);
248 static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD,
249 boolean preferIPv6Addresses);
252 * Query the IP stack for the local port to which this socket is bound.
255 * the socket descriptor
256 * @param preferIPv6Addresses
257 * address preference for nodes that support both IPv4 and IPv6
258 * @return the local port to which the socket is bound
260 public int getSocketLocalPort(FileDescriptor aFD,
261 boolean preferIPv6Addresses) {
262 return getSocketLocalPortImpl(aFD, preferIPv6Addresses);
265 static native int getSocketLocalPortImpl(FileDescriptor aFD,
266 boolean preferIPv6Addresses);
269 * Query the IP stack for the nominated socket option.
272 * the socket descriptor
274 * the socket option type
275 * @return the nominated socket option value
276 * @throws SocketException
277 * if the option is invalid
279 public Object getSocketOption(FileDescriptor fd, int opt)
280 throws SocketException {
281 return getSocketOptionImpl(fd, opt);
284 static native Object getSocketOptionImpl(FileDescriptor aFD, int opt)
285 throws SocketException;
287 public Channel inheritedChannel() {
288 return inheritedChannelImpl();
291 native Channel inheritedChannelImpl();
293 // BEGIN android-removed
294 // public boolean isReachableByICMP(final InetAddress dest,
295 // InetAddress source, final int ttl, final int timeout) {
296 // return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl,
300 // native int isReachableByICMPImpl(InetAddress addr,
301 // InetAddress local, int ttl, int timeout);
302 // END android-removed
304 public void listenStreamSocket(FileDescriptor aFD, int backlog)
305 throws SocketException {
306 listenStreamSocketImpl(aFD, backlog);
309 static native void listenStreamSocketImpl(FileDescriptor aFD, int backlog)
310 throws SocketException;
312 public void oneTimeInitialization(boolean jcl_supports_ipv6) {
313 if (!isNetworkInited) {
314 oneTimeInitializationImpl(jcl_supports_ipv6);
315 isNetworkInited = true;
319 native void oneTimeInitializationImpl (boolean jcl_supports_ipv6);
322 * Peek on the socket, update <code>sender</code> address and answer the
326 * the socket FileDescriptor
328 * an InetAddress, to be updated with the sender's address
329 * @param receiveTimeout
330 * the maximum length of time the socket should block, reading
331 * @return the sender port
333 * @throws IOException
334 * upon an read error or timeout
336 public int peekDatagram(FileDescriptor fd, InetAddress sender,
337 int receiveTimeout) throws IOException {
338 return peekDatagramImpl(fd, sender, receiveTimeout);
341 static native int peekDatagramImpl(FileDescriptor aFD,
342 InetAddress sender, int receiveTimeout) throws IOException;
345 * Read available bytes from the given file descriptor into a byte array.
347 * The read has an optional timeout parameter, which if non-zero is the
348 * length of time that the read will wait on a select call to see if any
349 * bytes are available for reading. If the timeout expires the method
350 * returns zero to indicate no bytes were read.
353 * the socket file descriptor to read
355 * the byte array in which to store the results
357 * the offset into the byte array in which to start reading the
360 * the maximum number of bytes to read
362 * the length of time to wait for the bytes, in milliseconds; or
363 * zero to indicate no timeout applied. When there is no timeout
364 * applied the read may block based upon socket options.
365 * @return number of bytes read, or zero if there were no bytes available
366 * before the timeout occurred, or -1 to indicate the socket is
368 * @throws IOException
369 * if an underlying socket exception occurred
371 public int read(FileDescriptor fd, byte[] data, int offset, int count,
372 int timeout) throws IOException {
373 return readSocketImpl(fd, data, offset, count, timeout);
376 static native int readSocketImpl(FileDescriptor aFD, byte[] data,
377 int offset, int count, int timeout) throws IOException;
380 * Read available bytes from the given file descriptor into OS memory at a
384 * the socket file descriptor to read
386 * the address of the memory in which to store the results
388 * the maximum number of bytes to read
390 * the length of time to wait for the bytes, in milliseconds
391 * @return number of bytes read, or zero if there were no bytes available
392 * before the timeout occurred, or -1 to indicate the socket is
394 * @throws IOException
395 * if an underlying socket exception occurred
397 public int readDirect(FileDescriptor fd, int address, int offset, int count,
398 int timeout) throws IOException {
399 return readSocketDirectImpl(fd, address, offset, count, timeout);
402 static native int readSocketDirectImpl(FileDescriptor aFD, int address, int offset, int count,
403 int timeout) throws IOException;
406 * Receive data on the socket into the specified buffer. The packet fields
407 * <code>data</code> & <code>length</code> are passed in addition to
408 * <code>packet</code> to eliminate the JNI field access calls.
411 * the socket FileDescriptor
413 * the DatagramPacket to receive into
415 * the data buffer of the packet
417 * the offset in the data buffer
419 * the length of the data buffer in the packet
420 * @param receiveTimeout
421 * the maximum length of time the socket should block, reading
423 * indicates to peek at the data
424 * @return number of data received
425 * @throws IOException
426 * upon an read error or timeout
428 public int receiveDatagram(FileDescriptor fd, DatagramPacket packet,
429 byte[] data, int offset, int length, int receiveTimeout,
430 boolean peek) throws IOException {
431 return receiveDatagramImpl(fd, packet, data, offset, length,
432 receiveTimeout, peek);
435 static native int receiveDatagramImpl(FileDescriptor aFD,
436 DatagramPacket packet, byte[] data, int offset, int length,
437 int receiveTimeout, boolean peek) throws IOException;
439 public int receiveDatagramDirect(FileDescriptor fd,
440 DatagramPacket packet, int address, int offset, int length,
441 int receiveTimeout, boolean peek) throws IOException {
442 return receiveDatagramDirectImpl(fd, packet, address, offset, length,
443 receiveTimeout, peek);
446 static native int receiveDatagramDirectImpl(FileDescriptor aFD,
447 DatagramPacket packet, int address, int offset, int length,
448 int receiveTimeout, boolean peek) throws IOException;
451 * Receive at most <code>count</code> bytes into the buffer
452 * <code>data</code> at the <code>offset</code> on the socket.
455 * the socket FileDescriptor
459 * the offset into the buffer
461 * the max number of bytes to receive
463 * the max time the read operation should block waiting for data
464 * @return the actual number of bytes read
465 * @throws IOException
466 * @throws SocketException
467 * if an error occurs while reading
468 * @deprecated use {@link #read(FileDescriptor, byte[], int, int, int)}
470 public int receiveStream(FileDescriptor aFD, byte[] data,
471 int offset, int count, int timeout) throws IOException {
472 return receiveStreamImpl(aFD, data, offset, count, timeout);
475 static native int receiveStreamImpl(FileDescriptor aFD, byte[] data,
476 int offset, int count, int timeout) throws IOException;
478 // BEGIN android-added
480 * Send <code>count</code> bytes from the buffer <code>data</code> at
481 * the <code>offset</code>, on the socket.
485 * @param data the send buffer @param offset the offset into the buffer
486 * @param count the number of bytes to receive @return int the actual number
487 * of bytes sent @throws IOException @exception SocketException if an error
488 * occurs while writing
490 public int sendStream(FileDescriptor fd, byte[] data, int offset, int count)
492 return sendStreamImpl(fd, data, offset, count);
495 static native int sendStreamImpl(FileDescriptor fd, byte[] data,
496 int offset, int count) throws IOException;
500 * Recieve data on the connected socket into the specified buffer. The
501 * packet fields <code>data</code> and <code>length</code> are passed in
502 * addition to <code>packet</code> to eliminate the JNI field access calls.
505 * the socket FileDescriptor
507 * the DatagramPacket to receive into
509 * the data buffer of the packet
511 * the offset in the data buffer
513 * the length of the data buffer in the packet
514 * @param receiveTimeout
515 * the maximum length of time the socket should block, reading
517 * indicates to peek at the data
518 * @return number of data received
519 * @throws IOException
520 * upon an read error or timeout
522 public int recvConnectedDatagram(FileDescriptor fd,
523 DatagramPacket packet, byte[] data, int offset, int length,
524 int receiveTimeout, boolean peek) throws IOException {
525 return recvConnectedDatagramImpl(fd, packet, data, offset, length,
526 receiveTimeout, peek);
529 static native int recvConnectedDatagramImpl(FileDescriptor aFD,
530 DatagramPacket packet, byte[] data, int offset, int length,
531 int receiveTimeout, boolean peek) throws IOException;
533 public int recvConnectedDatagramDirect(FileDescriptor aFD, DatagramPacket packet, int address,
534 int offset, int length, int receiveTimeout, boolean peek)
536 return recvConnectedDatagramDirectImpl(aFD, packet, address, offset, length, receiveTimeout, peek);
539 static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD,
540 DatagramPacket packet, int address, int offset, int length,
541 int receiveTimeout, boolean peek) throws IOException;
544 * Select the given file descriptors for read and write operations.
546 * The file descriptors passed in as readFDs will be selected for read-ready
547 * operations, and those in the writeFDs will be selected for write-ready
548 * operations. A file descriptor can appear in either or both array, and
549 * must not be <code>null</code>. If the file descriptor is closed during
550 * the select the behavior depends upon the underlying OS.
552 * Upon return the result is a single array of length
553 * <code>readFDs.length</code> + <code>writeFDs.length</code> laid out as
554 * the result of the select operation on the corresponding file descriptors.
557 * all sockets interested in read and accept
559 * all sockets interested in write and connect
561 * timeout in milliseconds
562 * @return each element describes the corresponding state of the descriptor
563 * in the read and write arrays.
564 * @throws SocketException
566 public int[] select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs,
567 long timeout) throws SocketException {
568 int countRead = readFDs.length;
569 int countWrite = writeFDs.length;
571 if (0 == countRead + countWrite) {
574 int[] flags = new int[countRead + countWrite];
576 assert validateFDs(readFDs, writeFDs) : "Invalid file descriptor arrays"; //$NON-NLS-1$
578 // handle timeout in native
579 result = selectImpl(readFDs, writeFDs, countRead, countWrite, flags,
585 if (ERRORCODE_SOCKET_TIMEOUT == result ||
586 ERRORCODE_SOCKET_INTERRUPTED == result) {
589 throw new SocketException();
592 static native int selectImpl(FileDescriptor[] readfd,
593 FileDescriptor[] writefd, int cread, int cwirte, int[] flags,
597 * Send the <code>data</code> to the address and port to which the was
598 * connected and <code>port</code>.
601 * the socket FileDescriptor
603 * the data buffer of the packet
605 * the offset in the data buffer
607 * the length of the data buffer in the packet
608 * @param bindToDevice
609 * not used, current kept in case needed as was the case for
611 * @return number of data send
612 * @throws IOException
613 * upon an read error or timeout
615 public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
616 int offset, int length, boolean bindToDevice) throws IOException {
617 return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice);
620 static native int sendConnectedDatagramImpl(FileDescriptor fd,
621 byte[] data, int offset, int length, boolean bindToDevice)
624 public int sendConnectedDatagramDirect(FileDescriptor fd,
625 int address, int offset, int length, boolean bindToDevice)
627 return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice);
629 static native int sendConnectedDatagramDirectImpl(FileDescriptor fd,
630 int address, int offset, int length, boolean bindToDevice)
634 * Send the <code>data</code> to the nominated target <code>address</code>
635 * and <code>port</code>. These values are derived from the DatagramPacket
636 * to reduce the field calls within JNI.
639 * the socket FileDescriptor
641 * the data buffer of the packet
643 * the offset in the data buffer
645 * the length of the data buffer in the packet
647 * the target host port
648 * @param bindToDevice
650 * @param trafficClass
651 * the traffic class to be used when the datagram is sent
653 * address to connect to.
654 * @return number of data send
656 * @throws IOException
657 * upon an read error or timeout
659 public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
660 int length, int port, boolean bindToDevice, int trafficClass,
661 InetAddress inetAddress) throws IOException {
662 return sendDatagramImpl(fd, data, offset, length, port, bindToDevice,
663 trafficClass, inetAddress);
666 static native int sendDatagramImpl(FileDescriptor fd, byte[] data, int offset,
667 int length, int port, boolean bindToDevice, int trafficClass,
668 InetAddress inetAddress) throws IOException;
670 public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
671 int length, int port, InetAddress inetAddress) throws IOException {
672 return sendDatagramImpl2(fd, data, offset, length, port, inetAddress);
675 static native int sendDatagramImpl2(FileDescriptor fd, byte[] data,
676 int offset, int length, int port, InetAddress inetAddress) throws IOException;
679 public int sendDatagramDirect(FileDescriptor fd, int address,
680 int offset, int length, int port, boolean bindToDevice,
681 int trafficClass, InetAddress inetAddress) throws IOException {
682 return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice,
683 trafficClass, inetAddress);
686 static native int sendDatagramDirectImpl(FileDescriptor fd, int address,
687 int offset, int length, int port, boolean bindToDevice,
688 int trafficClass, InetAddress inetAddress) throws IOException;
690 public void sendUrgentData(FileDescriptor fd, byte value) {
691 sendUrgentDataImpl(fd, value);
694 static native void sendUrgentDataImpl(FileDescriptor fd, byte value);
696 public void setInetAddress(InetAddress sender, byte[] address) {
697 setInetAddressImpl(sender, address);
700 native void setInetAddressImpl(InetAddress sender, byte[] address);
702 public void setNonBlocking(FileDescriptor fd, boolean block)
704 setNonBlockingImpl(fd, block);
707 static native void setNonBlockingImpl(FileDescriptor aFD, boolean block);
710 * Set the nominated socket option in the IP stack.
713 * the socket descriptor @param opt the option selector @param
714 * optVal the nominated option value
716 * @throws SocketException
717 * if the option is invalid or cannot be set
719 public void setSocketOption(FileDescriptor aFD, int opt,
720 Object optVal) throws SocketException {
721 setSocketOptionImpl(aFD, opt, optVal);
724 static native void setSocketOptionImpl(FileDescriptor aFD, int opt,
725 Object optVal) throws SocketException;
727 public void shutdownInput(FileDescriptor descriptor) throws IOException {
728 shutdownInputImpl(descriptor);
731 private native void shutdownInputImpl(FileDescriptor descriptor)
734 public void shutdownOutput(FileDescriptor fd) throws IOException {
735 shutdownOutputImpl(fd);
738 private native void shutdownOutputImpl(FileDescriptor descriptor)
741 * Close the socket in the IP stack.
744 * the socket descriptor
746 public void socketClose(FileDescriptor fd) throws IOException {
750 static native void socketCloseImpl(FileDescriptor fD);
752 public boolean supportsUrgentData(FileDescriptor fd) {
753 return supportsUrgentDataImpl(fd);
756 static native boolean supportsUrgentDataImpl(FileDescriptor fd);
759 * Used to check if the file descriptor arrays are valid before passing them
760 * into the select native call.
762 private boolean validateFDs(FileDescriptor[] readFDs,
763 FileDescriptor[] writeFDs) {
764 for (FileDescriptor fd : readFDs) {
765 // Also checks fd not null
770 for (FileDescriptor fd : writeFDs) {
779 * Write bytes from a byte array to a socket.
782 * the socket on which to write the bytes
784 * the array containing the bytes to be written
786 * the offset in the byte array from which to take the bytes
788 * the maximum number of bytes to be written. Callers are trusted
789 * not to send values of length+count that are larger than
791 * @return the actual number of bytes written, which will be between zero
793 * @throws IOException
794 * if there is an underlying socket problem
796 public int write(FileDescriptor fd, byte[] data, int offset, int count)
798 return writeSocketImpl(fd, data, offset, count);
801 static native int writeSocketImpl(FileDescriptor fd, byte[] data, int offset,
802 int count) throws IOException;
806 * Write bytes from the given address to a socket.
809 * the socket on which to write the bytes
811 * the start address of the bytes to be written
813 * the maximum number of bytes to be written
814 * @return the actual number of bytes written, which will be between zero
816 * @throws IOException
817 * if there is an underlying socket problem
819 public int writeDirect(FileDescriptor fd, int address, int offset, int count)
821 return writeSocketDirectImpl(fd, address, offset, count);
824 static native int writeSocketDirectImpl(FileDescriptor fd, int address, int offset, int count)