jdk 源码分析(19)java net包简单分析
来源:互联网 发布:怎么样开淘宝网店 编辑:程序博客网 时间:2024/06/10 02:15
jdk 源码分析(18)java net包只能简单分析,因为代码走到后面都变成了native方法,我去openJDK,以及其他语言的实现都没有找到底层怎么实现的,如果你知道,告诉我一声。
这里只能简单分析了。
1)通信代码:
服务端:
int port = 8919;
Socket socket =null;
ServerSocket server=null;
try {
server = new ServerSocket(port);
while(true) {
socket = server.accept();
//SocketInputStream
Reader reader = new InputStreamReader(socket.getInputStream());
char chars[] = new char[1024];
int len;
StringBuilder builder = new StringBuilder();
while ((len = reader.read(chars)) != -1) {
builder.append(new String(chars, 0, len));
}
System.out.println("Receive from client message=: " + builder);
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
socket.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
客户端代码:
String host = "127.0.0.1";
int port = 8919;
try {
Socket client = new Socket(host, port);
Writer writer = new OutputStreamWriter(client.getOutputStream());
writer.write("Hello From Client");
writer.flush();
writer.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
服务端
1)new ServerSocke
当new ServerSocket时候如果没有带入addr 将使用0.0.0.0作为默认的ip
最后new的socket 是一个native方法
PlainSocketImpl.java
static native int socket0(boolean stream, boolean v6Only)
或者TwoStacksPlainSocketImpl
native void socketCreate(boolean isServer) throws IOException;
上面两个类到底使用哪里实现类呢。下面的代码告诉我们有useDualStackImpl决定。
PlainSocketImpl() {
if (useDualStackImpl) {
impl = new DualStackPlainSocketImpl(exclusiveBind);
} else {
impl = new TwoStacksPlainSocketImpl(exclusiveBind);
}
}
这个值由系统决定。如果系统版本>=6.0或者IPV64 用DualStackPlainSocketImpl。
static {
java.security.AccessController.doPrivileged( new PrivilegedAction<Object>() {
public Object run() {
version = 0;
try {
version = Float.parseFloat(System.getProperties().getProperty("os.version"));
preferIPv4Stack = Boolean.parseBoolean(
System.getProperties().getProperty("java.net.preferIPv4Stack"));
exclBindProp = System.getProperty("sun.net.useExclusiveBind");
} catch (NumberFormatException e ) {
assert false : e;
}
return null; // nothing to return
} });
// (version >= 6.0) implies Vista or greater.
if (version >= 6.0 && !preferIPv4Stack) {
useDualStackImpl = true;
}
if (exclBindProp != null) {
// sun.net.useExclusiveBind is true
exclusiveBind = exclBindProp.length() == 0 ? true
: Boolean.parseBoolean(exclBindProp);
} else if (version < 6.0) {
exclusiveBind = false;
}
}
我的系统win7 所以有DualStackPlainSocketImpl决定。
2)accpet()
接着accpet 也是一个native方法
void socketAccept(SocketImpl s) throws IOExce2ption {
//如果
timeout没有设置就直接进入阻塞,一直等到数据过来。会阻塞是整个线程if (timeout <= 0) {
newfd = accept0(nativefd, isaa);
} else {
configureBlocking(nativefd, false);
try {
//否则等待有限时间,如果没有就退出
waitForNewConnection(nativefd, timeout);
newfd = accept0(nativefd, isaa);
if (newfd != -1) {
configureBlocking(newfd, true);
}
} finally {
configureBlocking(nativefd, true);
}
}
}
这里就是io不好的地方,会一直阻塞等待,而且如果同时来了两个线程,一次只能处理一个请求。另一个只能等待了。如果一般收到一个请求后会new 一个新的线程来处理,在新的线程里完成数据读写操作。,或者线程池来处理接收的数据。
3)读写数据。
socket.getInputStream()和socket.getOutputStream()
底层定义了SocketInputStream和SocketOutputStream不过read和write也是native 的。
客服端
客户new Socket()后,会去和指定的ip和端口连接,这个又是一个native 的方法,而且会一直尝试去连接。阻塞线程。
void socketConnect(InetAddress address, int port, int timeout)
throws IOException {
int nativefd = checkAndReturnNativeFD();
if (address == null)
throw new NullPointerException("inet address argument is null.");
int connectResult;
//不带超时的连接,
if (timeout <= 0) {
connectResult = connect0(nativefd, address, port);
} else {
//
带超时的连接,configureBlocking(nativefd, false);
try {
connectResult = connect0(nativefd, address, port);
if (connectResult == WOULDBLOCK) {
waitForConnect(nativefd, timeout);
}
} finally {
configureBlocking(nativefd, true);
}
}
/*
* We need to set the local port field. If bind was called
* previous to the connect (by the client) then localport field
* will already be set.
*/
if (localport == 0)
localport = localPort0(nativefd);
}
net里的网络连接是阻塞的,如果服务器端使用,一般每获取一个请求后启动一个新的线程,然后由新的线程处理数据。不再服务器接收请求的那里直接处理。当然也可以像nio那样,将一个线程专门处理接收,然后启动一个线程池,专门接收数据,然后一个线程池处理数据,一个线程池会写数据。
阅读全文
0 0
- jdk 源码分析(19)java net包简单分析
- jdk 源码分析(19)java net包简单分析
- jdk 源码分析(20)java NIO包简单分析
- jdk 源码分析(18)java io包分析
- jdk 源码分析(0) java 源码分析汇总
- jdk 源码分析(14)java ThreadLocal
- jdk并发包 CopyOnWriteArrayList源码分析
- jdk类库源码分析-各个包
- jdk 源码分析(9)java ReentrantReadWriteLock分析
- jdk 源码分析(10)java unsafe 分析
- jdk 源码分析(11)java ArrayBlockingQueue 缓存队列分析
- jdk 源码分析(15)java CountDownLatch 源码解析
- jdk 源码分析(16)java CyclicBarrier 源码解析
- jdk 源码分析(1)java hashmap的结构
- jdk 源码分析(4) java Set 结构
- jdk 源码分析(5)java ConcurrentSkipListMap结构
- jdk 源码分析(6)java BitSet结构
- jdk 源码分析(7)java ReentrantLock结构
- PAT基础题 4-2 多项式求值
- JMockit实践--(3)Expectations
- iOS Swift let和var的区别
- 【DP】Codeforces837D. Round Subset
- 三分学习 hdu 4454
- jdk 源码分析(19)java net包简单分析
- PAT基础题 4-3 简单求和
- centos7通过yum安装JDK1.8
- LeetCode 4Sum C++
- 《Unix网络编程》卷1:套接字联网API(第3版):简介、传输层、套接字编程
- JAVA 的重载是运行时决定还是编译的时候决定?正确使用泛型
- c++面向对象
- 比特币:一种P2P的电子现金体制
- 文件编程