Socket请求分析

来源:互联网 发布:上海师范大学网络课程 编辑:程序博客网 时间:2024/06/02 06:01

1, Socket

相对Http来说, Socket比较简单。

Proxy proxy = new Proxy(Proxy.Type.SOCKS,mSocketAddress);mSocket = new Socket(proxy);mSocket.connect(new InetSocketAddress("•••", •••)); mOutput = mSocket.getOutputStream();mInput = mSocket.getInputStream();

主要步骤如下:

1,构造Socket对象.

2, connect方法

3,获取OutputStream/InputStream对象

4,直接对OutputStream/InputStream对象进行操作。

Socket的构造方法有好几种,但是一般都是返回的是代理子类PlainSocketImpl对象。

本文章基于android 6.0

其中一种构造方法如下,

public Socket(Proxy proxy) {    if (proxy == null || proxy.type() == Proxy.Type.HTTP) {         throw new IllegalArgumentException("Invalid proxy: " + proxy);    }    this.proxy = proxy;    this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl(proxy);}

当然PlainSocketImpl也有好几种不同的构造方法。

2,connect

Socket对象的connect方法调用流程图如下,


Socket对象的connect方法主要逻辑如下,

1,首先调用PlainSocketImpl的bind方法进行绑定,

if (!usingSocks()) {     impl.bind(Inet6Address.ANY, 0);}

2,然后调用其connect方法进行连接,

impl.connect(remoteAddr, timeout);

从流程图来看, Socket的连接过程通过JNI对应的libcore_io_Posix.cpp最后到kernel完成。

3, OutputStream/ InputStream

Socket对象的getOutputStream方法如下,

checkOpenAndCreate(false);if (isOutputShutdown()) {     throw new SocketException("Socket output is shutdown");}return impl.getOutputStream();

直接调用PlainSocketImpl的getOutputStream方法,

return new PlainSocketOutputStream(this);

PlainSocketOutputStream是PlainSocketImpl的内部类。定义如下,

private static class PlainSocketOutputStream extends OutputStream {

其对应的write调用流程图如下,

InputStream和OutputStream的设计以及调用流程完全相同,其调用流程如下,


由此可见,Java文件的读写最后转化为Linux系统的文件读写。

HttpURLConnection和socket异同:

1,首先HttpURLConnection的连接是断续的, socket的连接是持续的,除非认为断开。

2,在内部, HttpURLConnection也是通过socket进行连接。

3,读写的不同, HttpURLConnection是利用Okio库进行读写,而socket最后是转化为Linux系统的文件读写。

原创粉丝点击