什么是网络编程
什么是网络编程,相比于编写程序在本机上运行,网络编程是指编写两台不同的计算机的程序,基于网络协议,通过网络进行数据通信。
常见的网络程序软件架构有:BS(Broser浏览器/Server服务器)架构、CS(Client客户端/Server服务器)架构
网络编程三要素
要实现网络编程,必须实现网络通信需要确定通信对象(IP)、对象中的具体程序(端口)、通信规则(协议)。
第一步,首先要在网络中,找到对方的计算机设备。计算机网络中,IP是网络设备的唯一地址。 第二步,在对方的计算机设备中,找到要通信的软件,因为计算机中可能运行很多程序。比如微信服务端要发送数据到用户手机,需要找到用户手机中的微信客户端,而用户手机中可能有微信、QQ、淘宝等很多应用程序。计算机网络中,端口号是区分程序进程的编号。 第三步,需要确定通信方式,即网络协议。计算机网络协议有TCP、UDP、HTTP等协议。
所以,网络编程的三要素就是:IP、端口号、网络协议
IP
IP是网络通信中,设备的地址,具有唯一性。
IP有IPV4和IPV6两种。
IPV4
IPV4是指IP互联网通信协议第四版,IPV4用4个字节共32位,用4组(每组1个字节)来表示,比如:11000000 10101000 00000001 00000001。IPV4采用点分十进制,即使用符号点.来分组,采用十进制表示。因此,上述IPV4地址表示为:192.168.1.1
IPV4共32位,因此可以区分的地址有2的32次方共计4,294,967,296,而全球有数十亿人,每个人又有数台可上网的设备。因此,IPV4的地址是不够用的,实际上,IPV4早在2019年就已经用完了。
IPV4已经用完了,而IPV6并没有大规模普及,那IPV4是如何解决当前设备IP地址不够的问题?答案是使用局域网。IPV4规定192.168.0.0~192.168.255.255这些为局域网IP(还有其他私有IP段,不展开),一个区域内(比如一个网吧)的所有设备,使用一个公网IP,而所有区域内的网络设备,使用局域网IP。局域网内的所有设备上网,都使用公网IP对外传输和接收数据,然后通过NAT(网络地址转换)技术,将局域网各设备的数据包,再分发给各自设备。
公网IP+局域网IP的技术,造成了我们目前使用设备的IPV4地址都是192.168.X.X的原因。
局域网IP地址,一般是路由器通过DHCP技术随机分配给网络设备的,一段时间后局域网IP地址会改版。除此之外,我们的设备在不同的上网环境,路由器分配的局域网地址一般都是不同的,比如在教师里连WIFI,笔记本电脑被分配的局域网地址可能是192.168.10.245,而回到寝室,连有线网,笔记本电脑被分配的局域网地址变成了192.168.1.3。因此,本机程序之间进行通信,不能使用局域网IP地址,而是使用一个被称为本机IP或者回环地址的特殊IP:127.0.0.1。网络设备在识别到回环地址作为目标地址,不会将数据传输到路由器或者网关,而是直接传给本机。
IPV6
为解决IP枯竭问题,IPV6横空出世。IPV6采用16个字节128位,共8组(每组两个字节)来表示,比如:11111101 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001。IPV6采用冒分十六进制,即使用符号冒号:来分组,采用十六进制来表示。因此,上述IPV6地址表示为:fd00:0000:0000:0000:0000:0000:0000:0001。由于IPV6地址很长,因此固定可以省略每一最前面的一连串0,因此上述IPV6地址可简写为:fd00:0:0:0:0:0:0:1。并且,规定可以进一步将中间的0省略,即压缩表示为:fd00::1
IPV6共128位,因此可以区分的地址为2的128次方个,可以为地球上每一粒沙子都分配一个唯一的IP地址。因此,IPV6一定是足够人们使用。目前,IPV6正在逐步推广,全面取代IPV4仍需时间,目前很多环境是双栈(IPV4+IPV6)运行。
端口
端口是计算机中应用程序向外发送数据/接收数据的“口”,每个应用程序都有一个端口号。
端口号是用两个字节来表示的,也就是一共有0~65535,一共65536个端口号。
应用程序启动时,操作系统会为应用程序分配一个端口号,应用程序就用这个端口号向网络收发数据。
协议
网络协议是指网络通信、数据传输的标准或规范。计算机网络中有OSI七层模型和TCP/IP模型,其中TCP/IP模型将网络划分为应用层、传输层、网络层和物理链路层,TCP/IP模型是行业默认的标准。
TCP/IP模型中不同层有不同的网络协议,比如HTTP、FTP等就是应用层的协议,而TCP、UDP是传输层的协议,IP是网络层的协议。
UDP 程序通信
UDP协议特点是无连接,发送后不管,所以速度快。
创建UDP发送数据的程序步骤:
// 发送端
public class SendMessage {
public static void main(String[] args) throws IOException {
// 1. 创建一个发送UDP的通信对象
DatagramSocket socket = new DatagramSocket();
// 2. 封装数据包
// 目的地址和端口
String ip = "127.0.0.1"; // 发送到本机,用回环地址
InetAddress destinationIP = InetAddress.getByName(ip); // 目的地址
int destinationPort = 10086;
// 待发送的数据
String data = "hello, world"; // 待发送的数据:hello, world
byte[] dataBytes = data.getBytes(); // 转换为字节数组
DatagramPacket packet = new DatagramPacket(dataBytes, dataBytes.length, destinationIP, destinationPort); // 数据包对象
// 3. 发送数据包
socket.send(packet);
// 4. 释放资源
socket.close();
}
}
UDP接收数据的程序步骤:
// 接收端
public class ReceiveMessage {
public static void main(String[] args) throws IOException {
// 1. 创建一个接收UDP的通信对象
DatagramSocket socket = new DatagramSocket(10086); // 指定接收端口为10086
// 2. 接收数据
byte[] buffer = new byte[1024]; // 创建一个1024字节的字节数组作为数据缓冲区,用于临时存储从网络接收到的数据
DatagramPacket packet = new DatagramPacket(buffer, buffer.length); // 创建一个数据包对象,最大接收数据长度为数组长度
socket.receive(packet);
// 3. 解析数据
byte[] data = packet.getData(); // 获取数据包中的数据
String receivedData = new String(data, 0, packet.getLength()); // 将数据转换为字符串
InetAddress sourceAddress = packet.getAddress(); // 获取发送方的IP地址
String sourceAddressStr = sourceAddress.getHostAddress(); // 解析为IP地址字符串
int sourcePort = packet.getPort(); // 获取发送方的端口号
// 打印出接收到的数据和发送方的IP地址及端口号
System.out.println("收到来自IP为" + sourceAddressStr + ",端口号为" + sourcePort + "的数据:" + receivedData);
// 4. 释放资源
socket.close();
}
}
收到来自IP为127.0.0.1,端口号为65290的数据:hello, world
进程已结束,退出代码为 0
TCP 程序通信
TCP协议是建立连接的协议,也就是在发送数据之前,需要先建立连接,连接建立失败则会异常,不可发送数据。TCP协议与UDP协议不同,TCP发送数据无需封装成数据包,还是通过数据流发送数据,因此发送和接收数据如同IO流。
TCP协议需要通过三次握手建立连接:
创建TCP发送消息的程序步骤为:
// 客户端
public class Client {
public static void main(String[] args) throws IOException {
// 1. 创建一个Socket对象
Socket socket = new Socket("127.0.0.1", 52522); // 指定接收端的IP和端口
// 2. 通过Socket对象获取输出流
OutputStream os = socket.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os); // 使用缓冲流(仅做演示,非必须)
OutputStreamWriter osw = new OutputStreamWriter(bos); // 使用OutputStreamWriter将字节流转换为字符流
osw.write("Hello, Server!"); // 写入数据
osw.flush(); // 刷新缓冲区,确保数据发送
// 3. 释放资源(按正确顺序)
osw.close(); // 释放字符流资源
bos.close(); // 释放缓冲流资源
socket.close(); // 释放Socket资源,自动关闭底层的字节输入流和字节输出流
}
}
创建TCP接收消息的程序步骤为:
// 服务器端
public class Server {
public static void main(String[] args) throws IOException {
// 1. 创建一个ServerSocket对象
ServerSocket serverSocket = new ServerSocket(52522);
// 2. 等待与客户端建立连接
Socket socket = serverSocket.accept(); // 链接建立后,返回一个Socket对象
// 3. 获得字节输入流对象
InputStream is = socket.getInputStream();
// 4. 将字节输入流转换为字符输入流,读取数据并打印成字符串
InputStreamReader isr = new InputStreamReader(is);
int len = 0;
char[] chs = new char[1024];
if ((len = isr.read(chs)) != –1) {
System.out.println(new String(chs, 0, len));
}
// 一般情况下,服务器端会循环接收多个客户端的请求
// 无需手动关闭Socket
// 5. 释放资源
isr.close(); // 关闭字符输入流
// is.close(); // 无需手动关闭字节输入流
socket.close(); // 关闭Socket,会自动关闭底层的字节输入流和字节输出流
}
}
TCP协议建立连接需要三次握手,关闭连接需要四次挥手。
网硕互联帮助中心






评论前必须登录!
注册