1
2
InetAddress
类代表IPwww.baidu.com
,www.mi.com
,www.sina.com
,www.jd.com
127.0.0.1
对应着localhost
public static InetAddress getLocalHost()
public static InetAddress getByNames(String host)
public String getHostAddress()
:返回IP地址字符串public String getHostName()
:返回此IP地址主机名public boolean isReachable(int timeout)
:测试是否可以连通此地址//1.获取本机地址ip对象
InetAddress ip1 = InetAddress.getLocalHost();
System.out.println(ip1.getHostName());//获取主机名字
System.out.println(ip1.getHostAddress());//获取ip地址
//2.获取域名ip对象
InetAddress ip2 = InetAddress.getByName("www.baidu.com");
System.out.println(ip2.getHostName());//获取域名
System.out.println(ip2.getHostAddress());//获取域名的ip地址
//3.获取公网对象
InetAddress ip3 = InetAddress.getByName("112.80.248.76");
System.out.println(ip3.getHostName());//获取公网名字
System.out.println(ip3.getHostAddress());//获取公网ip地址
//判断网络是否能连接通信 ping 5s之前测试是否能通过
System.out.println(ip3.isReachable(5000));//通过会返回true
正在计算机上运行的进程。
要求:不同的进程不同的端口号
范围:被规定为一个 16 位的整数0~65535
。
端口号与IP地址的组合得出一个网络套接字:Socket
TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。
SYN
(synchronize)标志的数据包给服务端;
seq
序列号,是由发送端随机生成的,并且将报文中的SYN
字段置为1,表示需要建立TCP连接。(SYN=1
,seq=x
,x
为随机生成数值)SYN/ACK
标志的数据包传递确认信息,表示我收到了;
seq
序列号,是由回复端随机生成的,并且将SYN
置为1,而且会产生ACK
字段,ACK
字段数值是在客户端发送过来的序列号seq
的基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP建立请求已得到验证。(SYN=1
,ACK=x+1
,seq=y
,y
为随机生成数值)这里的ack
加1可以理解为是确认和谁建立连接ACK
标志的数据包,表示我知道了,握手结束。
ACK
验证请求,在服务端发过来的seq
上加1进行回复。(SYN=1
,ACK=y+1
,seq=x+1
)SYN
标志位数置1,表示建立TCP连接;ACK
标志表示验证字段。
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN
来终止这个方向的连接。收到一个 FIN
只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN
后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
FIN
,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1
状态;
seq
序列号,是由发送端随机生成的,并且还将报文中的FIN
字段置为1,表示需要断开TCP连接。(FIN=1
,seq=x
,x
由客户端随机生成)FIN
后,发送一个ACK
给客户端,确认序号为收到序号+1(与SYN
相同,一个FIN
占用一个序号),服务端进入CLOSE_WAIT
状态;
seq
序列号,是由回复端随机生成的,而且会产生ACK
字段,ACK
字段数值是在客户端发过来的seq
序列号基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP断开请求已经得到验证。(FIN=1
,ACK=x+1
,seq=y
,y
由服务端随机生成)FIN
,用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK
状态;
FIN
字段置1,并且产生随机seq
序列号。(FIN=1
,ACK=x+1
,seq=z
,z
由服务端随机生成)FIN
后,客户端进入TIME_WAIT
状态,接着发送一个ACK
给Server,确认序号为收到序号+1,服务端进入CLOSED
状态,完成四次挥手。
seq
字段和ACK
字段,ACK
字段会在服务端的TCP断开请求的seq
基础上加1,从而完成服务端请求的验证回复。(FIN=1
,ACK=z+1
,seq=h
,h
为客户端随机生成)
至此TCP断开的4次挥手过程完毕其中:FIN
标志位数置1,表示断开TCP连接。
ServerSocket(int port)
:创建绑定到特定端口的服务器套接字ServerSocket(int port, int backlog)
:利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号ServerSocket(int port, int backlog, InetAddress address)
:使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器ServerSocket()
:创建非绑定服务器套接字。getLocalPort()
:返回此套接字在其上侦听的端口accept()
:侦听并接受到此套接字的连接setSoTimeout(int timeout)
:指定超时值bind(SocketAddress host, int backlog)
:将 ServerSocket 绑定到特定地址客户端要获取一个 Socket 对象通过实例化 ,而服务器端获得一个 Socket 对象是通过accept()
方法的返回值
Socket(String host, int port)
:创建一个流套接字并将其连接到指定主机上的指定端口号Socket(InetAddress host, int port)
:创建一个流套接字并将其连接到指定 IP 地址的指定端口号Socket(String host, int port, InetAddress localAddress, int localPort)
:创建一个指定主机和端口的套接字并将其连接到指定远程主机上的指定远程端口Socket(InetAddress host, int port, InetAddress localAddress, int localPort)
:创建一个指定ip和端口的套接字并将其连接到指定远程地址上的指定远程端口Socket()
:通过系统默认类型的 SocketImpl 创建未连接套接字connect(SocketAddress host, int timeout)
:将此套接字连接到服务器,并指定一个超时值getInetAddress()
:返回套接字连接的地址getPort()
:返回此套接字连接到的远程端口getLocalPort()
:返回此套接字绑定到的本地端口 getRemoteSocketAddress()
:返回此套接字连接的端点的地址,如果未连接则返回 nullgetInputStream()
:返回此套接字的输入流getOutputStream()
:返回此套接字的输出流close()
:关闭此套接字public static void main(String[] args) throws Exception{
//1、创建服务端管道
ServerSocket serverSocket = new ServerSocket(8080);
//2、阻塞等待客户端连接
Socket accept = serverSocket.accept();
System.out.println("有客户端连接:" + accept.getRemoteSocketAddress());
//3、从管道获取输入流,接收客户端消息
InputStream inputStream = accept.getInputStream();
//4、升级输入流为缓冲流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
//5、逐行读取数据
String s;
while ((s = bufferedReader.readLine()) != null){
System.out.println("客户端说:" + s);
}
bufferedReader.close();
}
public static void main(String[] args) throws Exception{
//1、创建客户端管道
Socket socket = new Socket("127.0.0.1",8080);
//2、从管道获取输出流,发送消息给服务端
OutputStream outputStream = socket.getOutputStream();
//3、升级输出流为打印流
PrintStream printStream = new PrintStream(outputStream);
//4、发送消息
printStream.println("你好呀,服务端!!!");
printStream.flush();
printStream.close();
}
DatagramSocket()
:绑定到本地地址和一个随机的端口号DatagramSocket(int port)
:绑定本地地址和一个特定的端口号DatagramSocket(int port, InetAddress iad)
:绑定到特定的端口号及指定地址DatagramSocket(SocketAddress sad)
:绑定指定地址和随机端口号close()
:关闭套接字recevie(DatagramPacket dp)
:接受数据报send(DatagramPacket dp)
:发送数据报
java.net
包中的 DatagramPacket 类用来表示数据报包,数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
DatagramPacket(byte[] buf, int length)
:用来接受长度为length的buf数据(即数据存于字节数组buf中)DatagramPacket(byte[] buf, int length, InetAddress address, int port)
:将length长的buf数据发送到指定的地址的端口号处DatagramPacket(byte[] buf, int length, SocketAddress address)
:将length长的buf数据发送到指定的套接字地址处public static void main(String[] args) throws Exception{
//1、创建UDP对象,自定义端口
DatagramSocket datagramSocket = new DatagramSocket(8080);
//2、创建容器接收数据
byte[] bytes = new byte[1024];
//3、创建接收数据包对象,将数据接收到bytes中
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
while (true){
//4、接收数据
datagramSocket.receive(datagramPacket);
SocketAddress address = datagramPacket.getSocketAddress();
//5、获取接收数据的长度
int length = datagramPacket.getLength();
System.out.println("收到数据:" + new String(bytes,0,length) + ",来自:" + address);
}
}
public static void main(String[] args) throws Exception{
//1、创建UDP对象
DatagramSocket datagramSocket = new DatagramSocket();
//发送五次数据
for (int i = 0; i < 5; i++) {
String s = "来自客户端的数据,第" + i + "次";
byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
//2、创建发送数据包对象
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("127.0.0.1"),8080);
//3、发送数据
datagramSocket.send(datagramPacket);
}
//4、关闭资源
datagramSocket.close();
}