目录
[3.1 IP地址](#3.1 IP地址)
[3.2 port端口](#3.2 port端口)
1.单机程序和网络程序
-
之前编写的程序都是单机程序,所有的业务功能实现及数据存储都在一个主机上完成,我们称为单机程序
-
我们在生活中使用的绝大多数的程序(应用,软件,app),都可以基于网络,与其他主机的程序进行数据交互,又不同的主机程序完成不同的业务功能。
2.客户端与服务端
-
在编写网络程序时,一般都会至少涉及两部分内容
-
客户端 : 主动发起连接的那个程序,就称为客户端程序。
-
服务端 : 接收连接信号的程序,就称为服务端程序。
3.网络编程三要素
3.1 IP地址
-
在网络环境中,每一个主机都会有一个唯一的网络标识,我们称为ip(地址)
-
在网络中可以通过ip,找到唯一的一个主机
-
ip标识的格式规范
-
IPV4 : 32bit,平均分成4分,来表示ip , 每一份8bit , 0~255
-
IPV6 : 128bit,平均分成6分,每一份使用16进制的数字来表示
-
-
使用本机ip地址
-
在cmd中,使用ipconfig命令,查看当前主机在局域网中的ip地址
-
如果连接本机,可以使用 localhost 或 127.0.0.1
-
3.2 port端口
-
计算机上运行的每一个程序,都会拥有一个(物理)端口
-
端口的作用就是实现程序内部与外部的数据通讯的。
-
随着程序启动,系统会自动的为程序的物理端口,分配一个数字标识,称为逻辑端口
- 在编写网络程序时,我们也可以手动为程序指定逻辑端口号
-
逻辑端口的数字范围 0~65535 , 其中0~1023 多作为系统程序的端口
-
如果一个程序的逻辑端口号,与另一个程序的逻辑端口号相同,我们称为端口号冲突
-
只能启动一个程序。
3.3 通讯协议
使用的通讯协议有两种
-
TCP : 一种安全型协议,能够包装数据传输的安全性,也就是能够保证双方一定能收到数据
通过3次握手,确保双方的网络是联通
通过4次挥手,确保双发的连接是断开的。
-
UDP : 一种不专注于数据安全传输的协议。适合广播,音频信息的传播。
4.TCP编程
Java中提供了**ServerSocket
**对象,可以充当服务端
public static void main(String[] args) throws IOException {
//启动了一个可以充当服务端的Java程序
ServerSocket server = new ServerSocket(6666);
}
Java中提供了**Socket
**对象,可以充当客户端
public static void main(String[] args) throws IOException {
//启动了一个可以充当客户端的Java程序
Socket client = new Socket("192.168.28.173" , 6666);
}
服务端程序启动后,需要等待客户端的连接
//等待客户端的连接,在等待过程中,当前线程会处于阻塞状态
//一旦客户端连接了,该方法会返回一个Socket对象
Socket client = server.accept();
public static void main(String[] args) throws IOException {
//启动了一个可以充当服务端的Java程序
ServerSocket server = new ServerSocket(6666);
System.out.println("======启动服务器========");
//等待客户端的连接
Socket link = server.accept();
System.out.println("收到了【"+link.getInetAddress()+"】客户端的连接");
}
-
一旦客户端和服务端产生了连接,接下来双方的交互都是基于Socket对象的。
-
两端的数据交互,最终是基于网络IO
-
Socket可以提供用于网络读写数据的IO流
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
注意:与文件io读取操作不同,网络数据没有一个明确的结束。
当使用**is.read()
**无法读取到数据时,默认不会获得-1,而是会阻塞等待
所以在使用网络io读写数据时,要提供一个结束标识,可以有两种方式
方式一:在a端使用**socket.shutdownOutput()
**,在b端通过-1结束
方式二:在a端额外传递一个结束字符串**os.write("[over]".getBytes())
**
在b端读取到结束字符串时就可以结束了。
5.UDP编程
-
编程语法上没有区分客户端对象和服务端对象 (逻辑上依然存储分别)
-
只要是UDP网络编程中的一个主机端,就需要创建**
DatagramSocket
**//如果当前的主机端作为逻辑服务端,需要指定端口 //如果当前的主机端作为逻辑客户都安,是否指定端口都可以。 DatagramSocket socket = new DatagramSocket(6666); DatagramSocket socket = new DatagramSocket();
-
UDP的数据传输,需要额外的一个对象**
DatagramPacket
** -
读写数据都需要依赖这个对象
java
//发数据时的packet构建,此时数组中要装有发送的内容
String str = "buka is good" ;
byte[] bs = str.getBytes();
DatagramPacket p = new DatagramPacket(
bs , 0 , bs.length,
InetAddress.getByName("localhost"),8888
);
//收数据时的packet构建,此时数组是一个空数组
byte[] bs = new byte[1024];
DatagramPacket p = new DatagramPacket(
bs , 0 , bs.length
);
- 实现数据包的发送和接收
java
//发送方发送数据
socket.send(p);
//接收接收数据,并获得发送方的一些信息(ip + port)
socket.receive(p);
String str = new String(p.getData(), 0, p.getLength());
System.out.println("收到来自【"+p.getSocketAddress()+":"+p.getPort()+"】的消息:" + str);