1.网络编程概述
1.计算机网络
把分布在不同地理位置的具有独特独立功能的就算机链接起来,由功能完善的软件实现软件资源共享和信息传递的系统。
java是Internet上的语言,它从语言级上提供了对网络应用程序的支持 , 程序员能够很容易开发常见的网络应用程序 。
java提供的网络类库,可以实现网络连接,联网的底层细节被隐藏在Java的本机安装系统里 由JVM进行控制。并且Java实现了一个跨平台的网络库 ,程序员面对的是一个统一的网络编程环境 。
2.网络通信三要素
1.IP
I P 地 址 ( I n t e r n e t P r o t o c o l A d d r e s s ) 是 指 互 联 网 协 议 地 址 , 又 译 为 网 际 协 议 地址 . 网 络 中 的 计 算 机 使 用 I P 地 址 来 进 行 唯 一 标 识。在 W i n d o w s 系 统 下 , 打 开 c m d , 输 入 命 令 i p c o n fi g , 按 回 车 即 可 查 看 。本 地 回 环 地 址 ( h o s t A d d r e s s ) : 1 2 7 . 0 . 0 . 1 , 它 代 表 设 备 的 本 地 虚 拟 接 口 .
2.端口号
端 口 号 是 计 算 机 中 的 应 用 程 序 的 一 个 整 数 数 字 标 号 , 用 来 区 分 不 同 的 应 用
程 序 。
3.通信协议
计 算 机 网 络 中 实 现 通 信 必 须 有 一 些 约 定 , 即 通 信 协 议 , 对 速 率 、 传 输 代
码 、 代 码 结 构 、 传 输 控 制 步 骤 、 出 错 控 制 等 制 定 标 准 。
3.网络通信协议
传 输 层 协 议 中 有 两 个 非 常 重 要 的 协 议 :
1.传 输 控 制 协 议 TC P ( Tr a n s m i s s i o n C o n t r o l P r o t o c o l )
2.用 户 数 据 报 协 议 U D P ( U s e r D a t a g r a m P r o t o c o l )
4.TCP
使 用 TC P 协 议 前 , 须 先 建 立 TC P 连 接 , 形 成 传 输 数 据 通 道
• 传 输 前 , 采 用 “ 三 次 握 手 ” 方 式 , 是 可 靠 的
• TC P 协 议 进 行 通 信 的 两 个 应 用 进 程 : 客 户 端 、 服 务 端
• 在 连 接 中 可 进 行 大 数 据 量 的 传 输
• 传 输 完 毕 , 需 释 放 已 建 立 的 连 接 , 效 率 低
• 在 断 开 时 要 进 行 “ 四 次 挥 手 ”
主要过程如下:
5.UDP
将 数 据 、 源 、 目 的 封 装 成 数 据 包 , 不 需 要 建 立 连 接
每 个 数 据 报 的 大 小 限 制 在 6 4 K 内
因 无 需 连 接 , 故 是 不 可 靠 的
发 送 数 据 结 束 时 无 需 释 放 资 源 , 速 度 快
2.TCP编程
在java中,我们实现TCP编程主要依靠Socket类来实现,首先我们来创建一个Socket对象。
Socket socket = new Socket("127.0.0.1", 9999);
其中127.0.0.1是服务器的域名,9999是其对应端口号,创建一个socket对象就是向服务器(域名是 127.0.0.1, 端 口 号 为9999 ) 发 起 TC P 连 接 , 若 成 功 , 则 创 建 S o c k e t 对 象 , 否 则 抛 出 异 常 。上面我们创建了一个客户端,接下来我们创建一个服务端,我们创建一个服务端需要使用ServerSocket类,需要注意的事情是如果我们只创建一个客户端没有创建一个服务端,那么运行后就会报错。
ServerSocket serverSocket = new ServerSocket(9999);
这样我们就创建出来了一个客户端和一个服务端。我们可以加入流的知识来实现客户端和服务端信息交流。
public class Client {//客户端,先启动服务端后在启动客户端
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
String s =null;
try {
while(true) {
Socket socket = new Socket("127.0.0.1", 9999);
OutputStream outputStream = socket.getOutputStream();//通过Socket类返回会得到一个OutputStream对象
s = sc.nextLine();
outputStream.write(s.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("链接服务器失败");
}
}
}
public class Server {
public static void main(String[] args) {
try {
//创建并启动服务器
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务器启动成功");
while (true) {
Socket accept = serverSocket.accept();//监听有没有客户端连接到服务器,会阻塞程序
System.out.println("客户端链接成功");
InputStream inputStream = accept.getInputStream();
byte[] b = new byte[100];
int read = inputStream.read(b);
String s = new String(b, 0, read);
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
}
}
}
上面两个代码只能客户端往服务端发送信息,下面的可以实现两边进行交流。
public class Client {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
while(true) {
Socket socket =new Socket("127.0.0.1",9999);
//向服务端发送消息
OutputStream outputStream = socket.getOutputStream();
DataOutputStream data = new DataOutputStream(outputStream);//数据处理流直接输出字符串
String s = sc.next();
data.writeUTF(s);
//接收服务器消息
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
System.out.println( dataInputStream.readUTF());
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器链接失败"+e.getMessage());
}
}
}
public class Server {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
try {
ServerSocket serverSocket =new ServerSocket(9999);
while(true) {
//接收客户端消息
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
System.out.println(dataInputStream.readUTF());
//给客户端发送消息
OutputStream outputStream = accept.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
String s = sc.next();
dataOutputStream.writeUTF(s);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("链接失败"+e.getMessage());
}
}
}
3.UDP编程
类DatagramSocket 和DatagramPacket 实现了基于 UDP 协议网络程序。UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。
UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。
public class Udpsend {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
//用来接受和发送数据的
DatagramSocket send =new DatagramSocket();
//封装一个数据包
/*
public DatagramPacket(byte buf[]字节, int offset 报文开始发送的位置, int length 结束的位置,
InetAddress address ip地址, int port端口号) {
setData(buf, offset, length);
setAddress(address);
setPort(port);
}
*/
while (true) {
byte[] b;
String s = sc.next();
b = s.getBytes();
DatagramPacket packet = new DatagramPacket(b, 0, b.length, InetAddress.getByName("127.0.0.1"), 9999);
send.send(packet);
System.out.println("发送完成");
}
}
}
public class UdpReceive {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket =new DatagramSocket(9999);
while (true){
//接收数据
//创建一个接收的数据宝
byte[] b =new byte[1024];
DatagramPacket datagramPacket =new DatagramPacket(b,0,b.length);
datagramSocket.receive(datagramPacket);
String s =new String(b,0,datagramPacket.getLength());
System.out.println(s);
}
}
}