源代码:https://gitee.com/AgentXiao/NetProgram
一、几个概念
1、网络
将不同区域的计算机连接到一起。简单氛围局域网、城域网、互联网
2、地址
即ip地址,确定计算机在网络上的一个绝对位置。相当于城市中的一栋房子
3、端口
区分计算机软件的。例如计算机安装了QQ、微信等不同软件,使用端口号实现不同的软件访问不同的服务器。相当于房子的窗户,每个窗户对应不同的软件。
特点:(1)2个字节 0-65535 共65536个
(2)1024以下的不要使用,因为是预留给计算机和各大厂商的,例如http -> 80,ftp -> 21
4、资源定位
统一资源定位符URL
统一资源URI
5、数据的传输
1)协议
TCP协议(transfer control protocol 传输控制协议)类比电话(面向连接,需要连接后才能通信)类似于三次握手,安全可靠但是效率低下
UDP协议(user datagram protocol 用户数据包协议)类比短信(非面向连接,不需要建立连接也可以通信)不安全但是效率高
2)传输
先封装、后拆封
二、类
底层还是流。学习网络编程实际上还是学习类的使用。
1、InetAddress:封装IP和DNS
这个类是没有构造方法的(构造),但是提供了静态方法用户创建InetAddress对象。创建InetAddress对象的三种方式及常用方法如下:
//InetAddress类没有构造方法,需要通过调用静态方法进行创建
//根据getLocalHost方法创建InetAddress对象
InetAddress addr = InetAddress.getLocalHost();//这是一个静态方法
System.out.println(addr.getHostName());//获得计算机名
System.out.println(addr.getHostAddress());//获得IP地址
//根据域名创建InetAddress对象
addr = InetAddress.getByName("www.baidu.com");
System.out.println(addr.getHostName());//获得计算机名
System.out.println(addr.getHostAddress());//获得IP地址
//根据IP地址创建InetAddress对象
addr = InetAddress.getByName("183.232.231.172");
System.out.println(addr.getHostName());//获得计算机名。如果没有解析,则返回自身
System.out.println(addr.getHostAddress());//获得IP地址
2、InetSocketAddress:封装端口
这个类相比于InetAddress还封装了端口号:
//通过构造方法创建InetSocketAddress对象,指定地址和端口
InetSocketAddress isa = new InetSocketAddress("localhost",9999);
//hostname是字符串时实际上也是调用了InetAddress.getByName("127.0.0.1")
//InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),9999);
System.out.println(isa.getPort());//获得端口
System.out.println(isa.getHostName());//获得计算机名称
InetAddress addr = isa.getAddress();
System.out.println(addr.getHostAddress());//获得IP地址
System.out.println(addr.getHostName());//获得计算机名
3、URL
URI(Uniform resource identifier)统一资源标识符,用来唯一的标识一个资源。
URL(Uniform Resource Locator)统一资源定位器,它是一种具体的URI 。
URL由四部分组成:协议+存放资源的主机名称+端口+资源文件名
java中的URL类:
1)常用构造方法
URL(String spec) :绝对路径构建
URL(URL context, String spec) :相对路径构建
2)常用方法
//绝对路径构建
URL url = new URL("http://www.baidu.com:80/index.jsp#aa?username=jack");
//相对路径构建
//URL url = new URL("http://www.baidu.com:80/a/");
//url = new URL(url,"b.jsp");
System.out.println(url.toString());
//常用方法
System.out.println("协议"+url.getProtocol());
System.out.println("域名"+url.getHost());
System.out.println("端口"+url.getPort());
System.out.println("资源"+url.getFile());
System.out.println("相对路径"+url.getPath());
System.out.println("锚点"+url.getRef());
System.out.println("参数"+url.getQuery());//如果存在锚点则返回null,因为参数被当做了锚点的一部分
}
}
3)流 openStream
URL url = new URL("http://www.baidu.com");//默认资源
//获得资源 网络流
InputStream is = url.openStream();
//输出:会乱码
// byte[] flush = new byte[1024];
// int len = 0;
// while(-1 != (len=is.read(flush))){
// System.out.println(new String(flush,0,len));
// }
// is.close();
//输出,不乱码
// BufferedReader bf = new BufferedReader(new InputStreamReader(url.openStream(),"utf-8"));
// String msg = null;
// while((msg = bf.readLine()) != null){
// System.out.println(msg);
// }
// bf.close();
//输出到本地
BufferedReader bf = new BufferedReader(new InputStreamReader(url.openStream(),"utf-8"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("baidu.html"),"utf-8"));
String msg = null;
while((msg = bf.readLine()) != null){
bw.append(msg);
bw.newLine();
}
bw.flush();
bw.close();
bf.close();
4、UDP通信
以数据为中心 非面向连接 不安全 数据可能丢失 效率高
客户端
1)创建客户端 DatagramSocket 类+指定端口
2)准备数据 字节数组
3)打包 DatagramPacket + 服务器地址及端口
4)发送
5)释放资源
//1、创建服务器端 + 端口
DatagramSocket server = new DatagramSocket(8888);
//2、准备接收容器
byte[] contains = new byte[1024];
//3、封装成包
DatagramPacket packet = new DatagramPacket(contains,contains.length);
//4、接收数据
server.receive(packet);
//5、分析数据
byte[] data = packet.getData();
int len = packet.getLength();
System.out.println(new String(data,0,len));
//6、释放资源
server.close();
服务器端
1)创建服务端 DatagramSocket 类+指定端口
2)准备接收容器 字节数组 封装 DatagramPacket
3)包 接收数据
4)分析
5)释放资源
//1、创建客户端 + 端口(同一台机器端口号不能重复)
DatagramSocket client = new DatagramSocket(6666);
//2、准备数据
byte[] data = "我爱你".getBytes();
//3、打包(发送的地点和端口)
DatagramPacket packet = new DatagramPacket(data,data.length,InetAddress.getByName("localhost"),8888);
//4、发送
client.send(packet);
//5、释放
client.close();
5、Socket编程
基于tcp: 面向连接 安全 可靠 效率低 ,类似于打电话
Socket编程示意图服务器:ServerSocket类
//1、创建服务器 指定端口
ServerSocket server = new ServerSocket(8888);
//2、接收客户端连接 阻塞式
Socket socket = server.accept();
System.out.println("一个客户端建立连接");
//3、发送数据
String msg = "欢迎使用";
// BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
// bw.write(msg);
// bw.newLine();//加行结束符
// bw.flush();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(msg);
dos.flush();
客户端:Socket类
//1、创建客户端 必须指定服务器端和端口
Socket client = new Socket("localhost",8888);
//2、接收数据
// BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
// System.out.println(br.readLine());//阻塞式方法,逐行读取,需要读取的数据有行结束符
DataInputStream dis = new DataInputStream(client.getInputStream());
System.out.println(dis.readUTF());
6、聊天室的设计
聊天室版本在这里我写了四个聊天室的版本,是循序渐进的,不断完善的。详见源代码。
版本1:
客户端可以发送和接收数据,但是只能实现单线程,就是只能实现一个用户发送后再接收。
版本2:
客户端新增发送和接收线程,两者独立工作,用户可以实现发生和接收的分离。但是服务器端仍然只能接收一个用户。
版本3:
改造服务器,为服务器添加用户容器,可同时添加多个用户及响应多个用户的数据发送和接收。
版本4:
新增私聊功能。
网友评论