本文主要介绍了网络编程的相关知识,首先介绍了互联网的相关概念和常见的体系架构,之后介绍了两种网络编程(TCP与UDP),并给出了代码实现!
一、名词概念
- 互联网(Internet): 点与点相连
- 万维网(www-world wide web): 端与端相连
- 物联网(IoT-Internet of things): 物与物相连
- 网络编程:
让计算机与计算机之间建立连接,进行通讯
二、网络架构
1.分层结构
2.OSI网络架构
- 简介: Open System Interconnect (开放式系统互连)
- 特点: 存在于概念和理论上的一种模型,它的缺点是分层太多,增加了网络工作的复杂性,所以没有大规模应用
- 第一层: :物理层为设备之间的数据通信提供传输信号和物理介质。(双绞线、 光导纤维)
作用: 建立、维护、断开物理连接。- 第二层: 链路层在物理层上,通过规程或协议(差错控制)来控制传输数据的正确性。(MAC)
作用: 接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,
拆装为位流形式的数据转发到物理层;并且,还负责处理接收端发回的确认帧的信息,以便提供可靠的数据传
输。- 第三层: 网络层负责定义了能够标识所有网络节点的逻辑地址。(IP地址)
作用: 逻辑寻址,IP地址,在下两层的基础上向资源子网提供服务- 第四层: 传输层负责是否选择差错恢复协议、数据流重用、错误顺序重排。(TCP、 UDP)
作用: 提供可靠和不可靠的传输机制,TCP、UDP- 第五层: 会话层负责使应用建立和维持会话,使通信在失效时继续恢复通信。(断点续传).
作用: 建立、终止、管理实体间的会话连接- 第六层: 表示层负责定义转换数据格式及加密,允许选择以二进制或ASCII格式传输。
作用: 封装数据的格式(加密解密、压缩解压缩)- 第七层: 应用层负责文件访问和管理、可靠运输服务、远程操作服务。(HTTP、 FTP、SMTP)
作用: 人与机器电脑交互的窗口
3.TCP/IP网络架构
- TCP协议: TCP协议: Transmission Control Protocol(传输控制协议)
解释: 是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。- UDP协议: User Datagram Protocol用户数据报协议
解释: 是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB。
IP协议: Internet Protocol Address(互联网协议地址/网际协议地址)
- 解释: 分配给互联网设备的数字标签(唯标识)。—— 计算机在互联网中的地址
- 分类:
IPv4
IPV6
IP对应类:InetAddress: 代码示例
public static void main(String[] args) throws IOException {
//获取本机地址
InetAddress inetAddress=InetAddress.getLocalHost();
System.out.println(inetAddress);
//通过主机名获取地址
InetAddress idAddress=InetAddress.getByName("DESKTOP-1028");
System.out.println(idAddress);
//通过主机名获取所有相关的地址对象
InetAddress[] inetAddresses = InetAddress.getAllByName("www.baidu.com");
for (InetAddress inetAddress2 : inetAddresses) {
System.out.println(inetAddress2);
}
//通过地址对象获取主机地址和主机名称
String hostAddress = inetAddress.getHostAddress();
String hostName = inetAddress.getHostName();
System.out.println(hostAddress);
System.out.println(hostName);
}
二、网络编程
1.Port端口
- 端口号: 在通信实体上进行网络通讯的 程序 的唯一标识。
- 端口分类:
公认端口: 0~1023
注册端口: 1024~49151
动态或私有端口: 49152~65535- 常用端口:
MySql: 3306
Oracle: 1521
Tomcat: 8080
SMTP: 25
Web服务器: 80
FTP服务器: 21
2.Socket编程
- Socket: 套接字,网络中的一个节点
- 通讯要求: IP地址+端口号
1.TCP编程
- 简介: 是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
- 注意: 分为客户端Scoket与服务器ServerSocket
开发步骤:
通过Socket获取到流,服务器才可以和客户端进行数据交互
- 服务端:ServerSocket
1,创建ServerSocket,指定端口
2,调用accept等待客户端接入(获取到客户端Socket映射)
3,使用Socket输入流或输出流,与客户端进行数据交互
4,关闭释放资源- 客户端:Socket
1,创建Socket对象,指定服务器IP+端口(获取到服务器Socket映射)
2,使用Socket获取到输出流,发起请求,给服务器发生数据(可选)
3,使用Socket获取到输入流,接收服务器返回的数据(可选)
4,关闭释放资源
TCP编程示例01:
无间断双向聊天
Task.java线程任务
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Task {
private Socket socket;
public Task() {
super();
}
public Task(Socket socket) {
super();
this.socket = socket;
}
//服务器功能线程
public void Message() {
//创建线程池(保证接收同步)
ExecutorService pool = Executors.newFixedThreadPool(2);
//接收消息线程
pool.submit(new Runnable() {
@Override
public void run() {
try {
//输入流
InputStream is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
while(true) {
String str = br.readLine();
System.out.println(str);
//判断是否关闭程序
if (str.equals("886")) {
break;
}
}
//关流
is.close();
socket.close();
isr.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
//发送消息线程
pool.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os);
BufferedWriter bw=new BufferedWriter(osw);
Scanner scanner=new Scanner(System.in);
//循环
while(true) {
String str=scanner.next();
bw.write(str);
bw.newLine();
bw.flush();
//跳出循环
if (str.equals("886")) {
break;
}
}
//关流
os.close();
socket.close();
osw.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
Server.java服务器端
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket=new ServerSocket(8899);
//获取到客户端映射
Socket socket=serverSocket.accept();
Task task=new Task(socket);
task.Message();
}
}
Client.java服务器端
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException{
// TODO Auto-generated method stub
Socket socket=new Socket("10.35.162.54", 9900);
Task task=new Task(socket);
task.Message();
}
**TCP编程示例02:
文件上传
**
Client.java服务器端
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket=new Socket("127.0.0.1", 8989);
System.out.println(socket.getInetAddress());
//获取输入流与输出流(与服务器交互)
InputStream is=socket.getInputStream();
OutputStream os=socket.getOutputStream();
//创建文件输入流(读取本地文件)
FileInputStream fis=new FileInputStream("E:\\dog.jpeg");
byte[] bytes=new byte[1024];
int len=0;
while((len=fis.read(bytes))!=-1) {
os.write(bytes, 0, len);
os.flush();
}
//获取服务器返回信息
len=is.read(bytes);
String str=new String(bytes, 0, len);
System.out.println(str);
}
}
注意:程序中服务器端文件流读取判断
Server.java服务器端
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
ServerSocket serverSocket = new ServerSocket(8989);
Socket socket = serverSocket.accept();
//获取输入流与输出流(用于和客户端交互)
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//创建文件输出流(将上传的照片保存到本地)
FileOutputStream fos = new FileOutputStream("E:\\smile.jpg");
byte[] bytes=new byte[1024];
int len=0;
while((len=is.read(bytes))!=-1) {
fos.write(bytes, 0, len);
fos.flush();
//只有文件才有EOF默认结束标志,
//并且EOF默认值为-1,所以可以判断是否为结束标志
//所以,当读取的数据没在文件中存储时,
//不会读取到-1值,其len表示的是读取长度,恒大于0不能作为循条件
if (len<1024) { //最后一段数据
break;
}
}
//反馈给客户端信息
os.write("你好客户端,我已经收到您上传的照片".getBytes());
//关流
fos.close();
is.close();
os.close();
}
}
2.UDP编程
- 简介: UDP协议是一种不可靠的网络协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB,速率快
注意: 分为接收端与发送端
开发步骤:
- 发送端:
1.创建发送端的Socket对象(DatagramSocket)
2.创建数据,并打包
3.调用DatagramSocket对象的方法发送数据
4.关闭发送端- 接收端:
1、创建接收端的Socket对象(DatagramSocket)
2、创建一个数据包,用于接收数据
3、调用DatagramSocket对象的方法接收数据
4、解析数据包,并在控制台显示
5、关闭接收端
文件传输
1.接收端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpGet {
public static void main(String[] args) throws IOException {
//1,创建接收端Socket
DatagramSocket socket = new DatagramSocket(9999);
//2,创建接收数据的包
byte[] b = new byte[1024];
DatagramPacket packet = new DatagramPacket(b, b.length);
//3,等待接收数据
socket.receive(packet);
//4,获取数据
byte[] data = packet.getData();
//5,获取数据长度
int length = packet.getLength();
//6,打印输出
System.out.println("接收的内容:"+new String(data,0,length));
//7,关闭资源
socket.close();
}
}
2.发送端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UdpSend {
public static void main(String[] args) throws IOException {
//1,创建发送端Socket对象
DatagramSocket socket = new DatagramSocket();
//2,准备发送内容
byte[] sendData = "要发送的内容".getBytes();
//3,接收端地址
InetAddress address = InetAddress.getByName(接收端的IP);
//4,封装发送信息包
DatagramPacket packet = new DatagramPacket(sendData,sendData.length, address, 9999);
//5,发送信息
socket.send(packet);
//6,关闭发送端
socket.close();
}
}