Java Socket, DatagramSocket, ServerSocketChannel这三个分别对应了,TCP, udp, NIO通信API封装。JDK封装了,想跟下代码,看下具体最后是怎么实现的。

都是通过native方法实现的。

下面是具体代码的跟进

1. Socket

                Socket clientSocket = serverSocket.accept();
InputStream is = clientSocket.getInputStream();
byte buff[] = new byte[1024];
length = is.read(buff);

上面的代码片段是从Socket读取数据的代码。跟进clientSocket.getInputStream()

/**
* Gets an InputStream for this socket.
*/
protected synchronized InputStream getInputStream() throws IOException {
synchronized (fdLock) {
if (isClosedOrPending())
throw new IOException("Socket Closed");
if (shut_rd)
throw new IOException("Socket input is shutdown");
if (socketInputStream == null)
socketInputStream = new SocketInputStream(this);
}
return socketInputStream;
}

这里拿到的是SocketInputStream对象,跟进SocketInputStream.read(byte[] buf)

/**
* Reads into a byte array data from the socket.
* @param b the buffer into which the data is read
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @exception IOException If an I/O error has occurred.
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}

继续跟进

/**
* Reads into a byte array <i>b</i> at offset <i>off</i>,
* <i>length</i> bytes of data.
* @param b the buffer into which the data is read
* @param off the start offset of the data
* @param length the maximum number of bytes read
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @exception IOException If an I/O error has occurred.
*/
public int read(byte b[], int off, int length) throws IOException {
return read(b, off, length, impl.getTimeout());
}

继续跟进

int read(byte b[], int off, int length, int timeout) throws IOException {
int n; // EOF already encountered
if (eof) {
return -1;
} // connection reset
if (impl.isConnectionReset()) {
throw new SocketException("Connection reset");
} // bounds check
if (length <= 0 || off < 0 || length > b.length - off) {
if (length == 0) {
return 0;
}
throw new ArrayIndexOutOfBoundsException("length == " + length
+ " off == " + off + " buffer length == " + b.length);
} boolean gotReset = false; // acquire file descriptor and do the read
FileDescriptor fd = impl.acquireFD();
try {
n = socketRead(fd, b, off, length, timeout);
if (n > 0) {
return n;
}
} catch (ConnectionResetException rstExc) {
gotReset = true;
} finally {
impl.releaseFD();
} /*
* We receive a "connection reset" but there may be bytes still
* buffered on the socket
*/
if (gotReset) {
impl.setConnectionResetPending();
impl.acquireFD();
try {
n = socketRead(fd, b, off, length, timeout);
if (n > 0) {
return n;
}
} catch (ConnectionResetException rstExc) {
} finally {
impl.releaseFD();
}
} /*
* If we get here we are at EOF, the socket has been closed,
* or the connection has been reset.
*/
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
}
if (impl.isConnectionResetPending()) {
impl.setConnectionReset();
}
if (impl.isConnectionReset()) {
throw new SocketException("Connection reset");
}
eof = true;
return -1;
}
socketRead(fd, b, off, length, timeout);跟进
private int socketRead(FileDescriptor fd,
byte b[], int off, int len,
int timeout)
throws IOException {
return socketRead0(fd, b, off, len, timeout);
}

继续跟进

private native int socketRead0(FileDescriptor fd,
byte b[], int off, int len,
int timeout)

2. DatagramSocket

clientSocket = new DatagramSocket();
packetToSend = new DatagramPacket(buff, buff.length, InetAddress.getByName("127.0.0.1"), 10002);
clientSocket.send(packetToSend); //发送数据包

跟进send()

public void send(DatagramPacket p) throws IOException  {
InetAddress packetAddress = null;
synchronized (p) {
if (isClosed())
throw new SocketException("Socket is closed");
checkAddress (p.getAddress(), "send");
if (connectState == ST_NOT_CONNECTED) {
// check the address is ok wiht the security manager on every send.
SecurityManager security = System.getSecurityManager(); // The reason you want to synchronize on datagram packet
// is because you don't want an applet to change the address
// while you are trying to send the packet for example
// after the security check but before the send.
if (security != null) {
if (p.getAddress().isMulticastAddress()) {
security.checkMulticast(p.getAddress());
} else {
security.checkConnect(p.getAddress().getHostAddress(),
p.getPort());
}
}
} else {
// we're connected
packetAddress = p.getAddress();
if (packetAddress == null) {
p.setAddress(connectedAddress);
p.setPort(connectedPort);
} else if ((!packetAddress.equals(connectedAddress)) ||
p.getPort() != connectedPort) {
throw new IllegalArgumentException("connected address " +
"and packet address" +
" differ");
}
}
// Check whether the socket is bound
if (!isBound())
bind(new InetSocketAddress(0));
// call the method to send
getImpl().send(p);
}

继续

    protected native void send(DatagramPacket p) throws IOException;

这里最后调用native方法

3.ServerSocketChannel

            SocketChannel client = server.accept();
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer);

继续

public abstract int read(ByteBuffer dst) throws IOException;

继续

public int read(ByteBuffer var1) throws IOException {
if (var1 == null) {
throw new NullPointerException();
} else {
Object var2 = this.readLock;
synchronized(this.readLock) {
if (!this.ensureReadOpen()) {
return -1;
} else {
int var3 = 0;
boolean var20 = false; byte var10000;
byte var5;
label356: {
int var27;
try {
var20 = true;
this.begin();
Object var4 = this.stateLock;
synchronized(this.stateLock) {
if (!this.isOpen()) {
var5 = 0;
var20 = false;
break label356;
} this.readerThread = NativeThread.current();
} while(true) {
var3 = IOUtil.read(this.fd, var1, -1L, nd);
if (var3 != -3 || !this.isOpen()) {
var27 = IOStatus.normalize(var3);
var20 = false;
break;
}
}
} finally {
if (var20) {
label271: {
this.readerCleanup();
this.end(var3 > 0 || var3 == -2);
Object var11 = this.stateLock;
synchronized(this.stateLock) {
if (var3 > 0 || this.isInputOpen) {
break label271;
} var10000 = -1;
} return var10000;
} assert IOStatus.check(var3); }
} label303: {
this.readerCleanup();
this.end(var3 > 0 || var3 == -2);
Object var28 = this.stateLock;
synchronized(this.stateLock) {
if (var3 > 0 || this.isInputOpen) {
break label303;
} var10000 = -1;
} return var10000;
} assert IOStatus.check(var3); return var27;
} this.readerCleanup();
this.end(var3 > 0 || var3 == -2);
Object var6 = this.stateLock;
synchronized(this.stateLock) {
if (var3 <= 0 && !this.isInputOpen) {
var10000 = -1;
return var10000;
}
} assert IOStatus.check(var3); return var5;
}
}
}
}
继续
static int read(FileDescriptor var0, ByteBuffer var1, long var2, NativeDispatcher var4) throws IOException {
if (var1.isReadOnly()) {
throw new IllegalArgumentException("Read-only buffer");
} else if (var1 instanceof DirectBuffer) {
return readIntoNativeBuffer(var0, var1, var2, var4);
} else {
ByteBuffer var5 = Util.getTemporaryDirectBuffer(var1.remaining()); int var7;
try {
int var6 = readIntoNativeBuffer(var0, var5, var2, var4);
var5.flip();
if (var6 > 0) {
var1.put(var5);
} var7 = var6;
} finally {
Util.offerFirstTemporaryDirectBuffer(var5);
} return var7;
}
}

继续

private static int readIntoNativeBuffer(FileDescriptor var0, ByteBuffer var1, long var2, NativeDispatcher var4) throws IOException {
int var5 = var1.position();
int var6 = var1.limit(); assert var5 <= var6; int var7 = var5 <= var6 ? var6 - var5 : 0;
if (var7 == 0) {
return 0;
} else {
boolean var8 = false;
int var9;
if (var2 != -1L) {
var9 = var4.pread(var0, ((DirectBuffer)var1).address() + (long)var5, var7, var2);
} else {
var9 = var4.read(var0, ((DirectBuffer)var1).address() + (long)var5, var7);
} if (var9 > 0) {
var1.position(var5 + var9);
} return var9;
}
}

继续

int read(FileDescriptor var1, long var2, int var4) throws IOException {
return FileDispatcherImpl.read0(var1, var2, var4);
}

继续

static native int read0(FileDescriptor var0, long var1, int var3) throws IOException;

最后都是native方法

JVM是c++. c实现的,最后调用的应该是c/c++的方法

 

Java Socket, DatagramSocket, ServerSocketChannel io代码跟踪的更多相关文章

  1. Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)

    声明:该博文以socket中,关闭输出流为例进行说明. 为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutpu ...

  2. Java Socket长连接示例代码

    SocketListenerPusher.java代码如下: import java.io.IOException; import java.net.InetSocketAddress; import ...

  3. Java Socket通信读取相关信息代码

    转自:http://developer.51cto.com/art/201003/190206.htm Java Socket通信读取有不少需要我们注意的知识点.当我们在使用的时候有很多的问题摆在我们 ...

  4. Java Socket/HttpURLConnection读取HTTP网页

    以读取百度的http网页为例.如果知道了IP地址和端口,然后新建一个Socket,就直接去读百度的首页,根本没反应,原因是www.baidu.com是以http协议传输的,而现在要以Socket原始的 ...

  5. Java Socket IO(BIO、NIO)

    总结下Java socket IO.首先是各种IO的定义,这个定义似乎也是众说纷纭.我按照stackoverflow上面的解释: IO有两种分法:按照阻塞或者按照同步.按照阻塞,有阻塞IO和非阻塞IO ...

  6. java scoket Blocking 阻塞IO socket通信四

    记住NIO在jdk1.7版本之前是同步非阻塞的,以前的inputsream是同步阻塞的,上面学习完成了Buffer现在我们来学习channel channel书双向的,以前阻塞的io的inputstr ...

  7. java socket编程实例代码

    1.所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 两性话题 两性 ...

  8. java scoket Blocking 阻塞IO socket通信一

    package bhz.bio; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; p ...

  9. java 提供了哪些IO方式

    今天听了杨晓峰老师的java 36讲,感觉IO这块是特别欠缺的,所以讲义摘录如下: 欢迎大家去订阅: 本文章转自:https://time.geekbang.org/column/article/83 ...

随机推荐

  1. 题解 UVA10212 【The Last Non-zero Digit.】

    题目链接 这题在学长讲完之后和看完题解之后才明白函数怎么构造. 这题构造一个$f(n)$ $f(n)$ $=$ $n$除以 $2^{a}$ $*$ $5^{b}$ ,$a$ , $b$ 分别是 $n$ ...

  2. 洛谷P4526 【模板】自适应辛普森法2(Simpson法)

    题面 传送门 题解 据说这函数在\(x>15\)的时候趋近于\(0\) 据说当且仅当\(a<0\)时积分发散 所以直接套自适应\(simpson\)吧-- //minamoto #incl ...

  3. Python3用sys和time模块实现进度条

    import sys import time def view_bar(num, total): rate = float(num) / float(total) rate_num = int(rat ...

  4. FJWC2019 子图 (三元环计数、四元环计数)

    给定 n 个点和 m 条边的一张图和一个值 k ,求图中边数为 k 的联通子图个数 mod 1e9+7. \(n \le 10^5, m \le 2 \times 10^5, 1 \le k \le ...

  5. angularJs表格效果

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...

  6. python之文件读写(1)

    1. 从文件读取数据 关于对文件的操作,使用open(filename, mode),打开文件.与之对应的,close()用来关闭文件.对文件操作完毕切记要关闭. open函数参数: mode 参数有 ...

  7. Contest Hunter 0601 Genius ACM

    Genius ACM Advanced CPU Manufacturer (ACM) is one of the best CPU manufacturer in the world. Every d ...

  8. POJ_2492 A Bug's Life 【并查集】

    一.题面 POJ2492 二.分析 并查集判断类别的题目感觉套路都差不多. 还是先判断在不在一个集合里,在一个集合里才能判断是否同类. 若不在一个集合里则需要将这两个点联系起来. 关于联系起来后关系的 ...

  9. SQL中的object_id函数

    关于SQL中的object_id函数:应该就是指系统表中存储着数据库的所有对象 每一个对象都有一个唯一的标识符Id进行标识object_id 就是根据对象名称返回改对象的Idobject_name 就 ...

  10. phpcms V9 框架目录结构

    phpcms v9框架的目录结构分析:      了解v9框架的目录结构,有助于帮助我们快速建立起对v9框架的一个整体认识 打开"mycms"项目,有如下文件和目录      使用 ...