网络编程总结
本文根据毕老师Java基础视频和自己的理解总结了Java网络编程部分的主要知识点
1. 网络数据传输和单机数据传输的区别是什么?
a. 单机数据传输是本机内硬件和硬件间的数据传输,网络传输是根据一种网络协议, 以某种网络通信的手段将本机的数据传给其他机器的数据, 反之亦然
b. 所以, 本质上网络数据传输在只是比单机数据传输多解决了如下几个问题:
b.1 如何找到一个网络上边的一个对方机器? IP地址+子网掩码;
b.2 如何定义机器间的通讯规则?网络传输协议
b.3 如何找到一个网络应用程序的在对方机器的开放位置? 端口;
2. IP地址是什么?
a. IP地址是来找到每个机器在网络中的位置的; 原有4段IP地址, 每段最高225;
b. 二级IP地址分为网络ID和主机ID, 网络ID用于识别计算机所处网段, 主机ID用于识别计算机所处网段内的具体位置
c. 三级IP地址分为网络ID,子网ID和主机ID, 网络ID+子网ID是一台机器所在子网的网络地址,而子网掩码是用来标记多少位是网络地址的(11...1,00.....0)
d. 同时子网掩码还限定了一个局域网内的最大连接机器数目, 在子网内的机器无需连接路由器即可相互通信
e. 电脑越来越多,4段不够用, IPv4扩展成IPv6, 是一个6段地址,而且还包含字母
f. 特殊的地址: 本地回环地址: 127.0.0.1; 每段最后一位: xxx.xxx.xxx.255是公共广播地址
3. Java中对IP地址封装了InetAddress类,这个类有什么特点和常用方法?
a. InetAdress: 无构造函数,静态方法调用生成一个地址对象
- 获得InetAddress本机对象: static InetAddress getLocalHost(); // 会出现UnknowHostException
- 获得指定名称/地址上的InetAddress对象: static InetAddress getByName(String(名称或地址)); // 同上
- 获得对应一个名称的一组InetAddress对象: static InetAddress[] getAllByName(String); //一个域名有多个地址
b. 获得得到InetAddress Host的名称和地址: 非静态方法
- String getHostName();
- String getHostAddress();
4. 网络传输协议是什么?
a. 国际组织定义了TCP/IP协议, 所有遵循这种通讯协议的电脑都可以根据这种协议互相通讯;
b. 协议有多种, 只要对方机器也有同样的一种协议就可以进行通讯; 为了安全, 有些组织和单位用自己特殊的通讯和协议
c. 主要介绍的协议是TCP和UDP协议
5. 端口是什么?
a. 此处的端口值得是网络端口, 每台基于IP地址的机器都有0-65535个端口可以用于进程于本机或者外界通讯
b. 0-1024一般是保留端口, 被一些知名服务占用, 后面的端口可以被分配给需要的进程使用
c. 遵循同一个协议的进程通讯不可以共用一个端口, 否则会出现冲突,但是,遵循不同协议的进程可以共用一个端口
6.Java的网络编程是在哪个层面运行的?
a. 网络传输的模型: OSI参考模型;TCP/IP参考模型
b. http; ftp是应用层; javaweb开发也是应用层的
c. java网络编程是在传输层(TCP/UDP)和网际层(IP)的java数据传输编程
7. UDP是什么,TCP是什么, 他们的区别是什么, 各有什么优劣?
a. UDP——User Datagram Protocol——聊天,视频会议,桌面共享等等
- 将数据及源和目的封装成数据包中,不需要建立连接
- 每个数据报的大小限制在64k内
- 因无连接,是不可靠协议
- 无需建立连接,速度快
- 类似对讲机
b. TCP——Transmission Control Protocol——下载
- 建立连接,形成传输数据的通道
- 在连接中进行大数据量传输
- 通过三次握手完成连接,是可靠协议
- 必须建立连接,效率会稍低
- 类似电话
c. TCP需要三次握手: Source-->Destination-->Source-->Destination
d. UDP求的是速度,不需要连接就可以发数据, 能不能接受不保证, 小包传输不保证数据的安全; TCP求的是安全的大数据传输,连接必须建立才能传输数据
8. 完成通信一定要有Socket, Socket是什么?
a.Socket是为网络服务提供的一种机制, 通信的两端都有Socket
b.数据在两个Socket间通过IO传输
c. 网络通信其实就是Socket间的通信
9. Java实现UDP的机制是什么?
a. Java将UDP机制封装在DatagramSocket类和DatagramPacket类中
b. DatagramSocket: 发送和接收DatagramPacket的Socket
c. DatagramPacket: 实现UDP的包投递服务; 包括数据,本机地址,目的地址
d. UDP发送端流程:
d.1 建立UDPSocket服务:
- DatagramSocket ds=new DatagramSocket(); //默认系统给分配标示,也可自己指定
d.2 提供数据:
- 通过IO流操作将数据从本机数据源读取成 bytes[]
d.3 将数据封装到数据包中并指定发送地址端口准备发送
- DatagramPacket dp; //bytes[]+length+InetAddress(To)+端口
d.4 通过socket服务的发送功能,将数据包发出去
- ds.sent(dp); // 如为绑定, 系统随机给发送端分配一个端口
d.5 关闭资源
- ds.close();
import java.net.*;
public class UDPSend {
public static void main(String[] args) throws Exception{
DatagramSocket ds=new DatagramSocket(); // --> d.1
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=bufr.readLine())!=null){
if("886".equals(line) // 停止条件
break;
byte[] buf=line.getBytes(); // --> d.2
DatagramPacket dp=new DatagramPacket(buf,buf.length
,InetAddress.getByName("127.0.0.1"),10001); // --> d.3
ds.send(dp); // --> d.4
}
ds.close(); // --> d.5
}
}
e.UDP接收
e.1建立UDPSocket服务,指定监听接受端口
- DatagramSocket sd=new DatagramSocket(int port); //指定接收端口
e.2定义数据包,用于存储接收到的字节数据,因为数据包对象中有更多功能可以使用来提取不同数据信息
- DatagramPacket dp=new DatagramPacket(buf,buf.length);
e.3通过socket服务的receive方法将收到的数据存储入已经定义好的数据包中
- ds.receive(dp); // 需要在e.1 中指定接收哪个端口
e.4 通过数据包对象的特有功能,将这些不同的数据取出, 通过IO流存储
- InetAddress getAddress
- byte[] getData()
- int getPort();
- int getLength(); 获得得到数据包的byte的长度
e.5 关闭资源
- ds.close();
import java.net.*;
public class UDPRec{
public static void main(String[] args) throws Exception{
while(true){
DatagramSocket ds=new DatagramSocket(10001); // --> e.1
byte[] buf=new byte[1024]; // --> e.2
DatagramPacket dp=new DatagramPacket(buf,buf.length); // --> e.2
ds.receive(dp); // --> e.3
String ip=dp.getAddress().getHostAddress();
String str=new String(dp.getData(),0,dp.getLength()); // --> e.4
System.out.println(ip+":"+str); // --> e.4
ds.close(); // --> e.5
}
}
}
10. Java 实现TCP的机制是什么?
a. Java实现TCP是通过Socket和ServerSocket两个类实现的
b. Socket实现客户端连接服务, ServerSocket实现服务器端连接服务
c. Socket和ServerSocket连接建立成功会自动形成一个内部连接通道(数据传输流)
d. 客户端TCP流程
d.1 创建客户端的socket服务,指定IP和port;
- Socket(IP,port);
d.2 获取Socket里面的输出流; 向此流中存入需要的数据(可以用IO方法)
- OutputStream getOutputStream();
d.3 通过Socket输出流的write方法把流写出传给服务端
- write();
d.4 需要关闭客户端输出流, 否则, 在之后接受服务器返回信息d.5时会互相等待
- shutdownOutput(); //关闭客户端输出流, 相对于给流中加入一个结束标记-1
d.5 接受服务器返回信息
- getInputStream();
d.6 关闭客户端服务
- close();
class TCPClient{
public static void main(String[] args) throws Exception{
Socket s=new Socket("127.0.0.1",10003); // --> e.1
BufferedReader bufr=new BufferedReader(new FileReader("a.txt")); // --> e.2
PrintWriter out=new PrintWriter(s.getOutputStream(),true); // --> e.2
String line=null;
while((line=bufr.readLine())!=null){
out.write(line); // --> e.3
}
s.shutdownOutput(); // --> e.4
BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); // --> d.5
System.out.println(in.readLine());
s.close(); // --> e.6
}
e. 服务端TCP流程
e.1 创建服务端Socket服务, 监听端口
- ServerSocket(port);
e.2 获取连接过来的客户端对象; 通过Socket可以得到客户端的各种信息
- Socket accept();
- getInetAddress();
e.3 客户端如果发来数据, 使用客户端对象, 并获取读取流来读取发来数据(可与其他IO流结合)
- InputStream getInputStream();
e.4 关闭服务器(可选操作)
- close();
e.5 服务器返回客户端信息(可选操作)
- getOutputStream();
- write()
class TCPServer{
public static void main(String[] args) throws Exception{
ServerSocket ss=new ServerSocket(10003); // --> e.1
Socket s=ss.accept(); // --> e.2
String ip=s.getInetAddress().getHostAddress(); // --> e.2
System.out.println(ip+" is connected!");
BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); // --> e.3
PrintWirter pw=new PrintWriter(new FileWriter("server.txt,true));
String line=null;
while((line=in.readLine())!=null){
pw.println(line);
}
PrintWriter out=new PrintWriter(s.getOutputStream(),true); // --> e.5
pw.print("Got it!");
}
}
11. Java 实现TCP UDP 的比较
a. UDP只用一个DatagramSocket可以在发送端和接收端实现数据传输服务的建立;而TCP分客户端Socket和服务端ServerSocket
b. UDP是通过DatagramPacket在发送端指定包裹接收IP和Port, 而TCP是在Socket建立时就去指定连接的IP和Port(因为TCP需要先连接再传输)
c. UDP以DatagramPacket的形式去投递数据, TCP以数据通道流的形式保证数据的安全传输
参考资料: 传智博客毕老师Java基础视频