java-网络编程
1. 网络编程相关术语
1. IP地址
- IP是互联网上的每一台计算机都有得一个唯一表示自己的标记。
- 分以下两个大类:
- IPv4:32位,分4段,0~255之间的十进制表示。使用4个8位的二进制数据表示,每8位之间使用圆点隔开,每个8位整数可以转换成一个0~255的十进制整数,因此我们一般看到的IP地址类似:192.168.1.1
- IPv6:128位,分8段,0000~FFFF的十六进制数值,冒号分割,如:1080:0:0:0:8:800:200C:417A
IP地址号段分类:A类留给政府机构,B类分配给中等规模的公司,C类分配给任意需要的人,D类用于组播(不是主播),E类用于实验,给类可容纳的地址数目不同

请写出几个你熟悉的DNS服务器地址。
| Google DNS | 8.8.8.8, 8.8.4.4 |
| Public DNS+ | 119.29.29.29 |
| 阿里 DNS | 223.6.6.6,223.5.5.5 |
| 百度 DNS | 180.76.76.76 |
| 360 DNS | 电信:101.226.4.6 联通:123.125.81.6 移动:101.226.4.6 铁通:101.226.4.6 |
3. InetAddress类表示IP地址,有两个子类
Inet4Address(IPv4)
Inet6Address(IPv6)
public static void main(String[] args) throws IOException {
// 1. getLocalHost() 返回本地主机的InetAddress对象
//相当于在dos窗口输入;ipconfig 查看本机的IP配置
InetAddress ia = InetAddress.getLocalHost();
System.out.println(ia); //DESKTOP-97KGRNJ/192.168.1.29
// 2.3 getHostName()与getHostAdress()方法获得本地主机的本机名,ip地址。
System.out.println(ia.getHostName()); //DESKTOP-97KGRNJ
System.out.println(ia.getHostAddress());//192.168.1.29
// 4. getByName(String host) 获取与Host相对应的InetAddress对象
InetAddress ia1 = InetAddress.getByName("DESKTOP-97KGRNJ");
System.out.println(ia1); //DESKTOP-97KGRNJ/192.168.1.29
// 5. byte[] getAddress() 返回此 InetAddress 对象的原始 IP 地址
byte[] b = ia1.getAddress();
System.out.println(Arrays.toString(b)); // [-64, -88, 1, 29]
// 反验证getAddress()方法
byte[] b1 = {(byte)192,(byte)168,(byte)1,(byte)29};
InetAddress ia2 = InetAddress.getByAddress(b1);
System.out.println(ia2.getHostName()); //DESKTOP-97KGRNJ
// 6. boolean isReachable(int timeout) 测试主机 是否可以和 某个地址联通
//相当于在dos窗口输入:(ping+ip地址) ping 192.168.1.29 (ping www.baidu.com)
boolean bool = ia2.isReachable(1000);
System.out.println(bool); //true 表示可以网络联通
}
2.端口 如果把IP地址比作一间房子的房号 ,端口就是出入这间房子的许多门(窗口)。 端口号只有整数,范围是从0 到65535(2^16-1)。
同一台机器上不能有两个程序使用同一个端口,会冲突
3. URL
- 什么是URL
URL(Uniform Resource Locator)统一资源定位符,可以直接使用此类找到互联网上的资源如一个简单的网页。
一般由:协议名,资源所在主机(域名),端口,资源名等部分组成;
如:http://itsource.cn:80/class_info/java_jichu.html
- URL类中的常用方法:
- 构造方法:URL(String protocol, String host, int port, String file)
- 方法 : InputStream openStream() 打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。
- 方法 :URI toURI() 返回与此 URL 等效的 URI
URL url = new URL("https://www.taobao.com/");
//1. InputStream openStream() 打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream
InputStream is = url.openStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while((line =br.readLine()) != null){
System.out.println(line); // 运行结果把淘宝网站的源代码读取出来了。
}
is.close();
4. URLEncoder与URLDecoder
// import java.net.URLDecoder;
// import java.net.URLEncoder; 显然是两个类
//2. URLEncoder.encode() 加码 URLDecoder.decode()解码
// 注意:对已经编码的进行编码,会继续编码,对已经解码的再解码,还是原来内容
String ss = URLEncoder.encode("你好","utf-8");
System.out.println(ss); // %E4%BD%A0%E5%A5%BD
String str = URLDecoder.decode("%E4%BD%A0%E5%A5%BD","utf-8");
System.out.println(str); //你好
5. Java的网络编程包括了两种通信协议:
TCP(Transmission Control Protocal) 传输控制协议
UDP(User Datagram Prptocol) 用数据包协议
TCP是面向连接的协议,因此每个TCP连接都有3个阶段:连接建立、数据传送和连接释放。
建立TCP需要三次握手才能建立,而断开连接则需要四次挥手。

第一次握手:建立连接时,客户端发送SYN包到服务器,并进入发送状态,等待服务器确认。
第二次握手:服务器收到SYN包,必须确认客户的SYN,同时自己也送一个SYN包,即SYN+ACK包,此时服务器进入接受状态。
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,此包发送完毕,客户端和服务器进入已建立状态,完成三次握手
TCP四次挥手过程如下:

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
- TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
- 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
- 服务器关闭客户端的连接,发送一个FIN给客户端。
- 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。
public class Server {
//模拟服务器端
public static void main(String[] args) throws IOException {
/*
*1.获取服务器端对象
*2.获取服务器端输入流
*3.读取流中的数据
*4.获取服务器端输出流
*5.往输出流中写数据
*6.关闭资源
*/
while(true){
ServerSocket serverSocket = new ServerSocket(6666);
Socket server = serverSocket.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(server.getInputStream()));
String data = null;
System.out.print("客户端:");
while((data = br.readLine())!= null){
System.out.println(data);
}
server.shutdownInput();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));
System.out.print("服务器说:");
String s = new Scanner(System.in).nextLine();
bw.write(s);
bw.close();
br.close();
server.close();
serverSocket.close();
}
}
}
public class client {
//模拟客户端发送数据
public static void main(String[] args) throws UnknownHostException, IOException {
/*
*1.获取客户端对象
*2.获取客户端输出流
*3.往流中写数据
*4.获取客户端输入流
*5.读取流中的数据
*6.关闭资源
*/
while(true){
Socket client = new Socket("127.0.0.1", 6666);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
System.out.print("客户端说:");
String s = new Scanner(System.in).nextLine();
bw.write(s);
bw.flush();
client.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
String data = null;
System.out.print("服务器端:");
while((data = br.readLine())!= null){
System.out.println(data);
}
br.close();
client.close();
}
}
}
UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。
- TCP的所有操作必须建立可靠的连接,这样会浪费很大的性能,为此UDP这种不可靠的连接出现并成为聊天工具的宠儿。
- UDP开发中使用DatagramPacket包装一条要发送的信息,之后使用DatagramSocket完成发送操作,也能够实现在两个终端之间传输数据。
//发送端
public class Send {
public static void main(String[] args) throws IOException {
/*1. 获取要发送的数据(信纸)
* 2.将数据封装到DatagramPacket 数据包,制定要发送的地址(信封)
* 3. 通过DatagramSocket对象(邮箱)的send方法发进行送
* 4.关闭数据
* */
/*构造方法 参数: 要发送的数据 发送数据多少 ip地址 端口号
* public DatagramPacket(byte buf[], int length,
InetAddress address, int port) {
this(buf, 0, length, address, port);
}*/
String data = "今天天气如何?";
DatagramPacket dp = new DatagramPacket(data.getBytes(),data.getBytes().length,InetAddress.getLocalHost(),8989);
DatagramSocket ds = new DatagramSocket();
ds.send(dp);
ds.close();
}
}
public class Receive {
public static void main(String[] args) throws IOException {
/*1.创建接受数据包的站点(DatagramSocket对象)
* 2. 通过DatagramSocket对象receive()接受发送端发过来的数据包
* 3.解析得到的数据包内的数据
* 4.关闭资源
* */
DatagramSocket ds =new DatagramSocket(8989);
//创建空的数据包,需要制定 空数据包 大小
byte [] b = new byte[1024]; //默认值全为 0
DatagramPacket dp = new DatagramPacket(b,b.length);
ds.receive(dp); //接受的信件保存到空数据包里面
byte[] data = dp.getData();//获取dp数据包的字节数组
System.out.println("发送端发送的数据:"+new String(Arrays.copyOf(data, dp.getLength())));
ds.close();
}
}
6. TCP与UDP的区别
1. 基于连接与无连接 ;
2. 对系统资源的要求(TCP较多,UDP少) ;
3. UDP程序结构较简单 ;
4. 流模式与数据报模式 ;
5. TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证(多个数据包的顺序);

浙公网安备 33010602011771号