1)连接到服务器
一、使用telnet
telnet 是windows上基于网络编程的调试工具,windows 可以在控制面版->程序->打开/关闭Windows特性,然后选择Telnet 客户端来开启windows 上telnet
可以通过两个基本的实验来认识telnet
输入:
telnet time-a.nist.gov 13
得到:
这里通过telnet 命令来连接远程服务器,这里连接的是国家标准和技术研究所所运维的,使用这个命令后会建立和服务13端口的会话,而对应的url 也会转换成ip地址129.6.15.28,随后talent 软件就会发送一个连接请求给地址,请求一个到端口13的连接,一旦建立连接,遍会发送回一行数据然后关闭这个连接,而一般的客户端和服务器之间往往会进行更多的会话。
输入:
telnet horstmann.com 80
返回:
因为这里是访问外网的原因可能迟迟没有给我消息,但是其实我是可以发送一个HTTP 的报文,向这个服务器提交请求
GET / HTTP/1.1
Host:horstmann.com
blank line
这样的GET请求服务器会返回我一个HTML 的页面代码
二、Java连接服务器
public class Test1 {
public static void main(String[] args) {
/*创建一个指定地址和端口的套接字,如果创建失败会抛出一个UnknownHostException*/
try (Socket s = new Socket("time-a.nist.gov",13);
Scanner in = new Scanner(s.getInputStream(),"utf-8")
){
while (in.hasNextLine()){
String line = in.nextLine();
System.out.println(line);
}
}catch (IOException e) {
/*如果存在host 不存在之外的异常会抛出一个IOException 异常
* UnknownHostException是这个异常的子异常
* */
e.printStackTrace();
}
}
}
套接字一旦创建成功就会建立与服务器对应的连接,java.net.Socket 类中的getInputStream 方法就会返回一个InputStream 对象,该对象可以像任何一个流对象一样去使用,相应的也可以把其中的信息输出在控制台。
Socket 类非常的易用,因为Java库隐藏了建立网络连接和通过连接发送数据的复杂过程,实际上,java.net 包提供的编程接口与操作文件时使用的接口基本相同。
java 支持传输层的TCP协议,也支持UDP协议。
解决超时
1、第一种超时是连接建立成功之后,在有数据可供访问之前,读操作会一直阻塞下去
Socket s = new Socket(...);
s.setTimeout(10000);
通过socket.setTimeOut方法可以设置套接字的超时时间,如果超过这个时间就会抛出SocketTimeoutException 异常,如果此时读操作和写操作在没有完成前就超时,可以通过捕获这个超时异常做出反应。
2、通过Socket 的构造器可以建立与服务器的连接,但是如果一直无法建立连接,就会一直阻塞下去,直到建立了连接。
可以通过:
Socket s =new Socket();
s.connect(new InetSocketAddress(host,port),timeout)
设置超时时间来处理一直无法连接上的问题。
三、因特网地址
就是通过域名来获取IP地址,一般的IP的地址是4字节的,而IPV6是16字节的,这时就可以通过**InetAddress类来实现**
只要主机支持IPV6格式的因特网地址,java.net 包也会支持它
获取指定域名的IP地址:
public class Test1 {
public static void main(String[] args) throws UnknownHostException {
String host = "www.baidu.com";
/*InetAddress address = InetAddress.getByAddress(host);*/
/*
一般的域名只会对应一个一个IP地址
而一些访问量比较大的域名会对应多个IP地址,从而实现负载均衡
可以通过上面的方法获取一个IP地址
也可以通过下面的方法获取一个域名对应的多个IP地址
*/
/*InetAddress 的toString方法会会返回一个字符串类型,进而打印会输出对应的ip地址*/
InetAddress[] addresses = InetAddress.getAllByName(host);
for (InetAddress address : addresses){
System.out.println(address);
}
}
}
如果想获取本地的IP地址可以通过:
public static void main(String[] args) throws UnknownHostException {
InetAddress address = InetAddress.getLocalHost();
System.out.println(address);
}
前面输出的是主机名而后面输出的是主机的IP地址
四、用到的API
java.netl.Sokcet 类
- Socket(String host,int port)
- 创建一个套接字,指定主机和端口
- Socket
- 创建一个为连接的套接字
- InputStream getInputStream()
- OutputStream getOutputStream()
- 获取从套接字中读取数据的流
- void connect(SocketAddress address)
- 将套接字连接到指定的地址
- void connect(SocketAddress address,int timeout)
- 连接到指定地址,如果给定时间内没有响应,则返回
- void setTimeout(int timeout)
- 设置套接字上的读请求的阻塞时间,超出给定时间抛出InterruptedIOException
- boolean isConnected()
- 如果该套接字被连接,则返回true
- boolean isClosed()
- 如果该套接字被关闭返回False
java.net.InetAddress类
- statci InetAddress getByName(String host)
- statci InetAddress[] getAllByName(String host)
- 给定主机名一个InetAddress 对象,或者一个数组
- static InetAddress getLocalHost()
- 为本机创建一个InetAddress 对象
- byte[] getAddress()
- 返回一个包含数字行地址的字节数组
- IP 地址的字节数组表示
- String getHostAddress()
- 返回值一个十进制组成的字符串,各数字用. 隔开
- 129.6.15.28
- String getHostName()
- 返回主机名