什么是网络编程?
在网络通信协议下,不同计算机上运行的程序,进行的数据传输。
- 应用场景:即时通信、网游对战、金融证券、国际贸易、邮件、等等。
不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输。
-
Java中可以使用java.net包下的技术轻松开发出常见的网络应用程序。
总结
-
什么网络编程?
计算机跟计算机之间通过网络进行数据传输。
-
常见软件架构有哪些?
CS/BS
-
通信的软件架构CS1BS的各有什么区别和优缺点
CS:客户端服务端模式需要开发客户端
BS:浏览器服务端模式不需要开发客户端。
CS:适合定制专业化的办公类软件如:IDEA、网游
BS:适合移动互联网应用,可以在任何地方随时访问的系统。
网络编程三要素
-
IP
设备在网络中的地址,是唯一的标识。
-
端口号
应用程序在设备中唯一的标识。
-
协议
数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。
总结
-
网络编程三要素分别是什么?
IP、端口号、协议
-
网络编程三要素分别表示什么?
IP:设备在网络中的地址,是唯一的标识
端口号:应用程序在设备中唯一的标识。
协议:数据在网络中传输的规则
常见的协议有UDP、TCP、http、https、ftp
IP
全称:Internet Protocol,是互联网协议地址,也称IP地址。
是分配给上网设备的数字标签。
通俗理解 上网设备在网络中的地址,是唯一的
常见的IP分类为IPV4、IPV6
IPv4
全称:Internet Protocol version4,互联网通信协议第四版。
采用32位地址长度,分成4组
IPv6
全称:Internet Protocol version6,互联网通信协议第六版。
由于互联网的蓬勃发展,IP地址的需求量愈来愈大,而引PV4的模式下IP的总数是有限的。
采用128位地址长度,分成8组。 2^128
IPV4的地址分类形式
- 公网地址(万维网使用)和私有地址(局域网使用)。
- 192.168.开头的就是私有址址,范围即为192.168.0.0–192.168.255.255,专门为组织机构内部使用,以此节省1P
特殊IP地址
127.0.0.1,也可以是localhost:是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在本机。
InetAddress类
端口号
应用程序在设备中唯一的标识。
端口号:由两个字节表示的整数,取值范围:0~65535
其中0~1023之间的端口号用于一些知名的网络服务或者应用。
我们自己使用1024以上的端口号就可以了。
注意:一个端口号只能被一个应用程序使用。
协议
计算机网络中,连接和通信的规则被称为网络通信协议
- OS引参考模型:世界互联协议标准,全球通信规范,单模型过于理想化,未能在因特网上进行广泛推广
- TCP/IP参考模型(或TCP/IP协议):事实上的国际标准。
OSI参考模型 | TCP/IP 参考模型 | TCP/IP 参考模型各层对应协议 | 面向哪些 |
---|---|---|---|
应用层 | 应用层 | HTTP\FTP\Telnet\DNS | |
表示层 | 应用层 | HTTP\FTP\Telnet\DNS | |
会话层 | 应用层 | HTTP\FTP\Telnet\DNS | |
传输层 | 传输层 | TCP\UDP… | 选择传输使用的TCP,UDP协议 |
网络层 | 网络层 | IP\ICMP\ARP | 封装IP |
数据链路层 | 物理+数据链路层 | 硬件设备 010101010101… | 转换成二进制利用物理设备传输 |
物理层 | 物理+数据链路层 | 硬件设备 010101010101… | 转换成二进制利用物理设备传输 |
UDP协议
用户数据报协议(User Datagram Protocol)
UDP是面向无连接通信协议。
速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据
TCP协议
传输控制协议TCP(Transmission Control Protocol)
TCP协议是面向连接的通信协议。
速度慢,没有大小限制,数据安全。
JDP通信程序
UDP通信程序(发送数据)
- 找快递公司 创建发送端的DatagramSocket对象
- 打包礼物 数据打包(DatagramPacket)
- 快递公司发送包裹 发送数据
- 付钱走人 释放资源
public class SendMessageDemo {
//发送数据通过Socket发送
public static void main(String[] args) throws IOException {
// 1. 创建Socket
DatagramSocket datagramSocket = new DatagramSocket();
byte buf[] = "Hello Word".getBytes(StandardCharsets.UTF_8);
int offset = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 10086;
// 打包数据,此处需要明确address, port这样创建的DatagramPacket才可以被发送
// 否则会提示 null address || null buffer
// 该构造函数有英文 Constructs a datagram packet for sending packets
DatagramPacket p = new DatagramPacket(buf, offset, address, port);
// 发送打包的内容并关闭Socket
datagramSocket.send(p);
datagramSocket.close();
}
}
UDP通信程序(接收数据)
- 找快递公司 创建接收端的DatagramSocketi对象
- 接收箱子 接收打包好的数据
- 从箱子里面获取礼物 解析数据包
- 签收走人 释放资源
public class ReceiveMessageDemo {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(PORT);
byte[] buf = new byte[1024];
DatagramPacket p = new DatagramPacket(buf, buf.length);
// 该方法是阻塞的
datagramSocket.receive(p);
System.out.println(new String(p.getData(), 0, p.getLength()));
datagramSocket.close();
}
}
发送与接收都使用到了DatagramSocket、DatagramPacket,DatagramPacket不指定端口号则代表为接收方,
DatagramSocket 的receive方法也代表了此文接收方。
UDP的三种通信方式
-
单播
以前的代码就是单播
-
组播
组播地址:
224.0.0.0 ~ 239 - 255.255.255
(其中 224.0.0.0 ~ 224.0.0.255 为预留的组播地址)
-
广播
广播地址:255.255.255.255
TCP通信程序
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象
通信之前要保证连接已经建立
通过Socket产生IO流来进行网络通信
综合练习
聊天室多发练习
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class ChatRoom {
public static void main(String[] args) throws IOException {
System.out.println("Please enter your username:");
Scanner scanner = new Scanner(System.in);
String username = scanner.nextLine();
User user = new User(username);
user.start();
}
}
class User {
private InetAddress group;
private int port;
private String username;
public User(String username) throws UnknownHostException {
this.group = InetAddress.getByName("224.0.0.1");
this.port = 8888;
this.username = username;
}
public void start() throws IOException {
MulticastSocket multicastSocket = new MulticastSocket(this.port);
multicastSocket.joinGroup(this.group);
new Thread(new RunnableTask(multicastSocket, this.username)).start();
System.out.println("Begin Chat...");
Scanner scanner = new Scanner(System.in);
while (true) {
String messages = scanner.nextLine();
messages = this.username + ":" + messages;
byte[] buf = messages.getBytes(StandardCharsets.UTF_8);
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, this.port);
multicastSocket.send(packet);
}
}
}
class RunnableTask implements Runnable {
private MulticastSocket multicastSocket;
private String username;
public RunnableTask(MulticastSocket multicastSocket, String username) {
this.multicastSocket = multicastSocket;
this.username = username;
}
@Override
public void run() {
byte[] bytes = new byte[1024];
while (true) {
try {
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
multicastSocket.receive(packet);
String userNameAndMessage = new String(packet.getData(), 0, packet.getLength());
if (userNameAndMessage.contains(this.username)) {
continue;
}
System.out.println(userNameAndMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
TCP 文件传输练习
注意点:客户端/服务端 发送完数据需要通过socket关闭OutPut,为了增加读写效率使用了Buffered流
客户端
import java.io.*;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 10000);
File file = new File("D:\\Program Files\\IdeaProjects\\mysocketnet\\clientdir\\1.png");
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
OutputStream outputStream = socket.getOutputStream();
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
// 数据缓冲区
byte[] bytes = new byte[1024];
int len;
while ((len = bufferedInputStream.read(bytes)) != -1) {
// 缓冲区最后一次的长度可能不是1024,需要通过InputStream.read 确定
bufferedOutputStream.write(bytes, 0, len);
}
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.println(bufferedReader.readLine());
socket.close();
}
}
服务端文章来源:https://www.toymoban.com/news/detail-447584.html
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(10000);
ExecutorService executorService = Executors.newCachedThreadPool();
while (true) {
Socket socket = serverSocket.accept();
executorService.submit(new MyRunnable(socket));
}
// serverSocket.close();
}
}
自定义任务文章来源地址https://www.toymoban.com/news/detail-447584.html
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class MyRunnable implements Runnable {
Socket socket;
public MyRunnable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
InputStream inputStream = null;
try {
inputStream = this.socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
String replace = UUID.randomUUID().toString().replace("-", "");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream("D:\\Program Files\\IdeaProjects\\mysocketnet\\serverdir\\" + replace + ".png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte[] bytes = new byte[1024];
int read = 0;
// inputStream.read 会一致读取,直到socket发送了shutdownOutput
while (true) {
try {
if ((read = inputStream.read(bytes)) != -1) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
try {
fileOutputStream.write(bytes, 0, read);
} catch (IOException e) {
e.printStackTrace();
}
}
OutputStream outputStream = null;
try {
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
String message = "数据接受完毕";
try {
outputStream.write(message.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
到了这里,关于Java网络编程(UDP、TCP)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!