网络编程:
1. 网络通信协议:
1. OSI参考模型
2. TCP/IP参考模型
2. 网络通信要素
1. IP和端口号
1.IP地址
- 唯一的标识 Internet 上的计算机(通信实体)
- 本地回环地址(hostAddress):127.0.0.1 主机名(hostName):localhost
- 分类方式
- IPV4 和 IPV6
- 公网地址(万维网使用)和私有地址(局域网使用)
2. 端口号
- 标识正在计算机上运行的进程(程序)
- 不同的进程有不同的端口号
- 被规定为一个 16 位的整数 0~65535
- 分类
- 公认端口:0~1023。被预先定义的服务通信占用
- 注册端口:1024~49151。分配给用户进程或应用程序
- 动态/私有端口:49152~65535
3. 端口号与IP地址的组合得出一个网络套接字:Socket
4. InetAddress类
- InetAddress类对象含有一个 Internet主机地址的域名和IP地址
- 域名容易记忆,当在连接网络时输入一个主机的域名后,域名服务器(DNS) 负责将域名转化成IP地址,这样才能和主机建立连接 — 这就是域名解析
- 实例化
- 没有公共的构造器,只能通过静态方法获取实例化对象
- public static InetAddress getLocalHost()
- 常用的方法
- public String getHostAddress():返回 IP 地址字符串(以文本表现形式)
- public String getHostName():获取此 IP 地址的主机名
- public boolean isReachable(int timeout):测试是否可以达到该地址
2. 网络协议
计算机网络中实现通信必须有一些约定,即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准
在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展
1.TCP/UDP
- 传输控制协议TCP(Transmission Control Protocol)
- 使用TCP协议前,须先建立TCP连接,形成传输数据通道
- 传输前,采用“三次握手”方式,点对点通信,是可靠的
- TCP协议进行通信的两个应用进程:客户端、服务端。
- 在连接中可进行大数据量的传输
- 传输完毕,需释放已建立的连接,效率低
- 用户数据报协议UDP(User Datagram Protocol)
- 将数据、源、目的封装成数据包,不需要建立连接
- 每个数据报的大小限制在64K内
- 发送不管对方是否准备好,接收方收到也不确认,故是不可靠的
- 可以广播发送
- 发送数据结束时无需释放资源,开销小,速度快
2. 传输控制协议(TCP)和网络互联协议(IP)
- IP(Internet Protocol)协议是网络层的主要协议
- TCP/IP协议模型从更实用的角度出发,形成了高效的四层体系结构,即 物理链路层、IP层、传输层和应用层
3. Socket(套接字)
网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字
通信的两端都要有Socket,是两台机器间通信的端点
网络通信其实就是Socket间的通信
Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输
一般主动发起通信的应用程序属客户端,等待通信请求的为服务端
分类:
- 流套接字(stream socket):使用TCP提供可依赖的字节流服务
- 数据报套接字(datagram socket):使用UDP提供“尽力而为”的数据报服务
常用构造器:
-
public Socket(InetAddress address,int port)创建一个流套接字并将其连接到指定 IP 地址的指定端口号
-
public Socket(String host,int port)创建一个流套接字并将其连接到指定主机上的指定端口号
常用方法:
3. TCP网络编程例子
//客户端
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Scanner sc = new Scanner(System.in);
//初始化Socket类对象,参数为IP地址和端口号
Socket socket = new Socket("127.0.0.1", 4567);
while (true) {
OutputStream os = socket.getOutputStream();
//传输从键盘输入的字符串转字节数组
os.write(sc.next().getBytes());
os.flush();
}
}
}
//服务器端
public class Service {
public static void main(String[] args) throws IOException {
//初始化ServerSocket对象,确定好接收的端口号
ServerSocket socket = new ServerSocket(4567);
while (true) {
// 调用accept返回客户端套接字
Socket s = socket.accept();
InputStream is = s.getInputStream();
byte[] b = new byte[4096];
int len = 0;
while ((len = is.read(b)) != -1) {
String str = new String(b, 0, len);
System.out.println(str);
}
}
}
}
4. UDP网络编程例子
//服务器端
public class Service {
public static void main(String[] args) throws IOException {
//数据报套接字对象,确定服务器端口号
DatagramSocket ds = new DatagramSocket(5555);
byte[] b = new byte[1024];
//初始化数据报的包对象
DatagramPacket dp = new DatagramPacket(b, b.length);
//接收客户端的数据报
ds.receive(dp);
String str = new String(b,0,b.length);
System.out.println(str);
ds.close();
}
}
//客户端
public class Client {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(6666,InetAddress.getByName("127.0.0.1"));
//获取端口号
int port = ds.getLocalPort();
//获取本地IP地址
String address = ds.getLocalAddress().toString();
byte[] bs = (port + address).getBytes();
//确定服务器端的IP地址和端口号
DatagramPacket dp = new DatagramPacket(bs, bs.length,InetAddress.getByName("127.0.0.1"),5555);
//发送数据报
ds.send(dp);
ds.close();
}
}
5. URL网络编程
以上笔记大多来自于尚硅谷~