作者:jijs
链接:http://www.jianshu.com/p/f8d78149a465
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Socket构造
-
public Socket()
构造一个Socket,因为没有指定目标主机和端口,所以不会通过网络进行连接。
-
public Socket(Proxy proxy)
通过一个代理构建一个未连接的Socket。
-
public Socket(String host, int port)
通过一个主机和端口构建一个Socket。构造Socket的时候会连接目标主机,如果连接不到目标主机则会抛出IOException或UnknownHostException异常。
-
public Socket(InetAddress address, int port)
通过一个InetAddress 和端口构建一个Socket,构造的时候也会进行连接目标主机,同3。
-
public Socket(String host, int port, InetAddress localAddr, int localPort)
通过一个要连接的远程主机和端口,并指定从本地哪个ip和端口连接。
-
public Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
通过一个要连接的远程主机和端口,并指定从本地哪个ip和端口连接。同5。
获取Socket相关的信息
获取远程主机相关信息
1 public SocketAddress getRemoteSocketAddress() 2 public InetAddress getInetAddress() 3 public int getPort()
获取本地相关信息
1 public SocketAddress getLocalSocketAddress() 2 public InetAddress getLocalAddress() 3 public int getLocalPort()
上面6个方法获取本地和远程主机端口相关的信息。如果socket未连接则返回null,如果socket已经关闭则返回已经连接过的本地和远程主机端口的信息。
connect方法
1 public void connect(SocketAddress endpoint) 2 public void connect(SocketAddress endpoint, int timeout)
connet放提供了两个方法,一个是传入一个SocketAddress 进行连接目标地址
另一个是通过一个SocketAddress 和超时等待时间来连接目标地址。
代码示例:
1 Socket socket = new Socket(); 2 SocketAddress socketAddr = new InetSocketAddress("www.baidu.com", 80); 3 socket.connect(socketAddr); 4 //socket.connect(socketAddr, 2000); 5
代码中使用了Socket的空构造函数进行构造Socket对象。空构造不会进行连接目标主机(因为没有设置目标地址),需要使用connet方法进行连接目标主机。
代理服务器
1 //构造代理服务器地址 2 SocketAddress sa = new InetSocketAddress("192.168.10.130", 808); 3 //构造Socket代理 4 Proxy proxy = new Proxy(Proxy.Type.SOCKS, sa); 5 //使用代理创建socket 6 Socket socket = new Socket(proxy); 7 //构造目标地址 8 SocketAddress socketAddr = new InetSocketAddress("www.baidu.com", 80); 9 //socket使用代理连接目标地址 10 socket.connect(socketAddr); 11
使用public Socket(Proxy proxy)构造方法来构造一个使用proxy的socket。
以后使用该socket的相关的网络操作都会通过代理服务器进行连接。
读取、写入数据
使用下面两个放进行向远程主机读取数据和写入数据进行交互。
1 public InputStream getInputStream() 2 public OutputStream getOutputStream()
通过这两个方法我们可以发现,使用socket进行交换操作,其实就是对流的操作。
下面是使用getInputStream和getOutputStream方法对远程主机进行交换的示例。
1 Socket socket = new Socket("127.0.0.1", 9000); 2 OutputStream os = socket.getOutputStream(); 3 //通过OutputStream流向远程服务器写如数据 4 ... 5 InputStream is = socket.getInputStream(); 6 //通过InputStream流读取响应的数据。 7 ... 8 9
半关闭连接
如果想关闭socket的输入或输出则可以使用一下两个方法。
1 public void shutdownInput() 2 public void shutdownOutput()
当调用shutdownInput()时,则不允许再次从socket中读取数据。
当调用shutdownOutPut()方法后会告诉流已经输入完成,不允许再次输入。对方读取流时,会接受到流结束标志(会返回-1)。
但关闭输入或输出是不会关闭socket的,因为他们不会释放本地端口,还需要调用socket的close()方法来关闭socket。
下面两个方法来判断socket的输入或输出流是否关闭。
1 public boolean isInputShutdown() 2 public boolean isOutputShutdown()
如果socket未连接(通过空构造方法构造的socket),也会返回false(未关闭状态)。
判断socket是否关闭
1 //是否连接过目标地址 2 public boolean isConnected() 3 //是否关闭过socket 4 public boolean isClosed()
isConnected方法并不是连接状态才返回true,而是只要连接过目标地址就返回true,哪怕已经关闭的socket也会返回true的。
isClosed方法是判断socket是否调用close()方法关闭过socket。
如果使用空构造方法构建socket而不连接目标主机,还没调用close方法,该方法会返回true。
所以要判断该socket是否连接目标地址需要这样判断
1 //打开过连接,但还没有关闭连接 2 if(socket.isConnected() && !socket.isClosed()){ 3 System.out.println("连接状态"); 4 }else{ 5 System.out.println("未打开连接或已经关闭连接"); 6 } 7 8