Java Socket, DatagramSocket, ServerSocketChannel io代码跟踪
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代码跟踪的更多相关文章
- Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)
声明:该博文以socket中,关闭输出流为例进行说明. 为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutpu ...
- Java Socket长连接示例代码
SocketListenerPusher.java代码如下: import java.io.IOException; import java.net.InetSocketAddress; import ...
- Java Socket通信读取相关信息代码
转自:http://developer.51cto.com/art/201003/190206.htm Java Socket通信读取有不少需要我们注意的知识点.当我们在使用的时候有很多的问题摆在我们 ...
- Java Socket/HttpURLConnection读取HTTP网页
以读取百度的http网页为例.如果知道了IP地址和端口,然后新建一个Socket,就直接去读百度的首页,根本没反应,原因是www.baidu.com是以http协议传输的,而现在要以Socket原始的 ...
- Java Socket IO(BIO、NIO)
总结下Java socket IO.首先是各种IO的定义,这个定义似乎也是众说纷纭.我按照stackoverflow上面的解释: IO有两种分法:按照阻塞或者按照同步.按照阻塞,有阻塞IO和非阻塞IO ...
- java scoket Blocking 阻塞IO socket通信四
记住NIO在jdk1.7版本之前是同步非阻塞的,以前的inputsream是同步阻塞的,上面学习完成了Buffer现在我们来学习channel channel书双向的,以前阻塞的io的inputstr ...
- java socket编程实例代码
1.所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 两性话题 两性 ...
- java scoket Blocking 阻塞IO socket通信一
package bhz.bio; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; p ...
- java 提供了哪些IO方式
今天听了杨晓峰老师的java 36讲,感觉IO这块是特别欠缺的,所以讲义摘录如下: 欢迎大家去订阅: 本文章转自:https://time.geekbang.org/column/article/83 ...
随机推荐
- ajax的get,post ,封装
let ajax = new Object(); ajax.get = function(url,fn){ //创建ajax对象 let xhr = new XMLHttpRequest(); //与 ...
- VS2010 UAC执行级别修改
配置属性 -> 链接器 -> 清单文件 -> UAC执行级别 改为 requireAdministrator 这个级别即可.
- [转]An STL compliant sorted vector-源码示例
原文地址:http://www.codeproject.com/Articles/3217/An-STL-compliant-sorted-vector 最近在看sorted vectored的一些东 ...
- GCD - Extreme (II) UVA - 11426 数学
Given the value of N , you will have to nd the value of G . The de nition of G is given below: G = i ...
- 网址访问量统计插件 FlagCounter
网址或博客访问量统计插件 ---> FlagCounter. 网址:http://s01.flagcounter.com/more/ERP2/
- Eclipse工程部署到Tomcat时出现中文乱码问题
1.修改Server.xml文件:添加URIEncoding="UTF-8" <?xml version="1.0" encoding="UTF ...
- Kibana6.x.x源码分析--Error: $injector:nomod Module Unavailable
首先我的依赖注入写法如下: 由于是新手,比对着Kinaba中已有的插件,进行摸索开发,但运行代码后,发现在注册依赖的时候报错了.如下截图所示: 然后根据提示:http://errors.angular ...
- CodeChef - RIN 最小割应用 规划问题
题意:给定\(n\)门课和\(m\)个学期,每门课在每个学期有不同的得分,需要选定一个学期去完成,但存在约束条件,共有\(k\)对课程需要\(a\)在\(b\)开始学前学会,求最大得分(原问题是求最高 ...
- VBS映射网络驱动器 映射网络驱动器
Dim objNetwork Set objNetwork = CreateObject("Wscript.Network") if objNetwork.EnumNetworkD ...
- PIE SDK中值滤波
1.算法功能简介 中值滤波是一种最常用的非线性平滑滤波器,它将窗口内的所有像素值按高低排序后,取中间值作为中心像素的新值. 中值滤波对噪声有良好的滤除作用,特别是在滤除噪声的同时,能够保护信号的边缘, ...