网络编程
就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。
网络通信三要素
IP地址:InetAddress
网络中设备的标识,不易记忆,可用主机名
/*
* IP : 每个接入互联网的计算,都有一个独立的身份标识 IP地址
* 同一个网内,IP地址都是唯一性
* IP地址组成:
* 4个数字段位组成
* 0.0.0.0 0-255 1个字节
* 数字多,长,不好记, 记住我的域名就可以了
* www.XXX.com -> IP地址
* DNS
* www.baidu.com -> 百度计算机在互联网上的IP
*
* 127.0.0.1 本机回环地址,每个接入网络的主机,自己找自己
* 通过IP 127.0.0.1 表示自己的主机
* 192.168 开头,局域网固定IP地址
*/
/* java.net
类 InetAddress
java.lang.Object
java.net.InetAddress
这个类的构造方法私有了 不能通过new来创建对象
但是这个类有一个静态方法static InetAddress getLocalHost() 返回本地主机。
*/
import java.net.*;
public class InetDemo1 {
public static void main(String[] args) throws Exception {
InetAddress i = InetAddress.getLocalHost();//静态方法类名调
System.out.println(i);//如果是哈希值就没重写toString方法
System.out.println("-------------------");
//这样我们就拿到了InetAddress 类的对象就可以用方法了
// String getHostAddress()
// 返回 IP 地址字符串(以文本表现形式)。
String s = i.getHostAddress();
System.out.println(s);
System.out.println("-------------------");
// String getHostName()
// 获取此 IP 地址的主机名。
String s1 = i.getHostName();
System.out.println(s1);
//static InetAddress getByName(String host)
// 在给定主机名的情况下确定主机的 IP 地址。
String s2 = InetAddress.getByName("dell-pc").getHostAddress();
System.out.println(s2);
}
}
端口号
用于标识进程的逻辑地址,不同进程的标识
物理端口 网卡口
逻辑端口 我们指的就是逻辑端口
A:每个网络程序都会至少有一个逻辑端口
B:用于标识进程的逻辑地址,不同进程的标识
C:有效端口:0~65535,其中0~1024系统使用或保留端口。
通过360可以查看端口号
传输协议
通讯的规则
常见协议:TCP,UDP
这里用到了3个类! 如下:
java.net.Socket 负责客户端和服务器取得连接的对象
DatagramPacket 将数据,IP,端口号封装成数据包
DatagramSocket 将数据包,进行投递,接收
他们的方法我就写在具体的列子中了~
1. UDP
协议特点
|-- 面向无连接
|-- 不可靠协议
|-- 限制64KB
|-- 运行速度快
UDP的发送接收
/*
* 实现UDP发送端
* DatagramPacket 将数据,IP,端口号封装成数据包
* DatagramSocket 将数据包,进行投递,接收
*
* DatagramPacket 发送端作用
* 构造方法
* DatagramPacket(byte[] buf, int length, InetAddress address, int port)
* 字节数组 , 数组长度,IP地址对象,端口号 0-1024 不能超过65535
*
* DatagramSocket 发送端作用
* 构造方法,空参数
* 发送方法 void send(DatagramPacket d)
*
* 实现思路:
* DatagramPacket将数据封装成数据包,字节数组,IP,端口
* DatagramSocket对象,用来发送
* 将数据包放到 DatagramSocket类的方法send
* 关闭Socket资源
*/
public class UDPSend {
public static void main(String[] args) throws Exception {
//DatagramPacket 数据封包
byte[] bytes = "你好UDP".getBytes();
DatagramPacket dp = new
DatagramPacket(bytes, bytes.length,InetAddress.getByName("192.168.12.83"),8000);
//创建DatagramSocket对象,负责投递
DatagramSocket ds = new DatagramSocket(5000);
//调用Socket服务方法send传递数据包
ds.send(dp);
//关闭资源
ds.close();
}
}
/*
* 实现UDP接收端
* DatagramPacket 需要接收的字节数组
* DatagramSocket 将数据包,接收
*
* DatagramPacket 接收端
* 构造方法
* DatagramPacket(byte[] buf, int length)
* 字节数组,用数组的多长去接收
* 用于拆包方法
*
* InetAddress getAddress() 获取到发送端的IP地址对象
* 继续使用IP对象,获取IP和主机名
*
* int getLength() 获取到发送的有效字节个数
* int getPort() 获取发送的端口号
*
* DatagramSocket 接收
* 构造方法
* DatagramSocket(int port) 传递端口号
* 接收数据包的方法
* void receive(DatagramPacket p) 线程阻塞效果
*
实现思路
创建DatagramPacket,接收发来字节数组
创建DatagramSocket receive接收数据包
使用DatagramPacket类的方法,进行拆包
关闭资源
*/
public class UDPReceive {
public static void main(String[] args) throws Exception {
// 定义字节数组,不能超过64K
byte[] bytes = new byte[1024];
// 创建DatagramSocket对象,开启端口
DatagramSocket ds = new DatagramSocket(8000);
while (true) {
// 创建数据包对象,传递字节数组
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
// 使用receive接收数据包
ds.receive(dp);
// 开始拆包动作
// 拆发送的IP地址
String ip = dp.getAddress().getHostAddress();
// 拆发送端口号
int port = dp.getPort();
// 拆发送的有效字节个数
int length = dp.getLength();
String message = new String(bytes, 0, length);
if("886".equals(message)){
System.out.println(ip + ".." + port + ".."+ "离开了");
}else{
System.out.println(ip + ".." + port + ".."+ message);
}
// 输出发送的数据 IP 端口, 数据,字节数组变成字符串
}
// 关闭资源
// ds.close();
}
}
- TCP
协议特点
|– 面向连接
|– 三次握手取得连接,速度慢
|– 可靠协议
|– 适合大数据传输
TCP的方式与接收如下:
/*
* 实现TCP客户端
* java.net.Socket
* 负责客户端和服务器取得连接的对象
*
* Socket类构造方法
* Socket(String host, int port)
* 传递字符串IP, int端口号
* new Socket("1.11.11.1",10000) 运行就会去连接服务器,如果此时没有服务程序,抛出异常
*
* 从Socket类的对象中获取IO流对象
* InputStream getInputStream() 字节输入流,读取服务器发回的数据
* read()
* OuputStream getOutputStream()字节输出流,向服务器发送数据
* write()
*
* 向服务器发送数据 实现思路
* 创建Socket去连接服务器
* 从Socket对象中获取字节输出流
* 方法write写向服务器
* 关闭资源
*/
public class TCPClient {
public static void main(String[] args)throws Exception {
Socket s = new Socket("192.168.12.83",8000);
//通过Socket对象获取自己输出流
OutputStream out = s.getOutputStream();
//写的方法
out.write("你好TCP".getBytes());
//通过Socket对象,获取字节输入流,读取服务器发回的数据
InputStream in = s.getInputStream();
byte[] bytes = new byte[1024];
int len = in.read(bytes);
System.out.println(new String(bytes,0,len));
//关闭资源
s.close();
}
}
/*
* 实现TCP服务器端
* java.net.ServerSocket
* 负责服务器和客户端的连接对象
* ServerSocket类构造方法
* ServerSocket(int port)
* 传递端口号,服务器程序开启,就会打开端口号
*
* 服务器必须要知道哪个客户端和我连接上了
* Socket accept() 返回的是客户端的连接对象
* 线程阻塞方法,等着客户端
* 使用客户端连接对象Socket获取IO对象
*
* InputStream getInputStream() 获取字节输入流,读取客户端发送的数据
* OutputStream getOutputStream() 获取字节输出流,向客户端写数据
*
* TCP服务器读取客户端数据实现思想
* 建立ServerSocket 打开端
* accept获取客户端连接
* 客户端连接,获取IO流
* 关闭资源
*/
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String[] args) throws Exception{
//创建ServerSocket对象,开启端口
ServerSocket ss = new ServerSocket(8000);
//ServerSocket类的方法accept获取客户端连接对象
Socket s = ss.accept();
//通过客户端连接对象获取IO字节输入流,读取客户端的数据
InputStream in = s.getInputStream();
byte[] bytes = new byte[1024];
int len = in.read(bytes);
System.out.println(new String(bytes,0,len));
//通过Socket对象,获取字节输出流,将数据写回客户端
OutputStream out = s.getOutputStream();
out.write("Ok已经收到".getBytes());
s.close();
ss.close();
}
}
TCP传输,服务器接收时候,注意: 一定要先有 ServerSocket(int port)