网络通信三要素:协议,IP,端口。七层协议。
package com.qianfeng.test;
/*
* 网络编程基础:
* 网络的通信:三要素:协议,IP,端口
* 1.IP:在网络上唯一的标记一台主机 127.0.0.1 :保留地址/本地地址 java将IP面向对象了形成的类叫InetAddress
* 2.端口:一台主机上的多个服务器 取值范围(0,65535) 注意:在通信时要保证客户端和服务器端使用的端口号一致
* 3.协议:制定的一个统一的标准
*
*
* 七层协议: 了解
* 应用层
与其它计算机进行通讯的一个应用,它是对应应用程序的通信服务的。
例如,一个没有通信功能的字处理程序就不能执行通信的代码,
从事字处理工作的程序员也不关心OSI的第7层。但是,如果添加了一个
传输文件的选项,那么字处理器的程序员就需要实现OSI的第7层。
示例:TELNET,HTTP,FTP,NFS,SMTP等。
表示层
这一层的主要功能是定义数据格式及加密。例如,FTP允许你选择以二进制
或ASCII格式传输。如果选择二进制,那么发送方和接收方不改变文件的内容。
如果选择ASCII格式,发送方将把文本从发送方的字符集转换成标准的ASCII后
发送数据。在接收方将标准的ASCII转换成接收方计算机的字符集。示例:加密,ASCII等。
会话层
它定义了如何开始、控制和结束一个会话,包括对多个双向消息的控制和管理,
以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的,
在某些情况下,如果表示层收到了所有的数据,则用数据代表表示层。示例:RPC,SQL等。
传输层
这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在同一主机上对不同
应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能。
示例:TCP,UDP,SPX。
网络层
这层对端到端的包传输进行定义,它定义了能够标识所有结点的逻辑地址,还定义了
路由实现的方式和学习的方式。为了适应最大传输单元长度小于包长度的传输介质,
网络层还定义了如何将一个包分解成更小的包的分段方法。示例:IP,IPX等。
数据链路层
它定义了在单个链路上如何传输数据。这些协议与被讨论的各种介质有关。示例:ATM,FDDI等。
物理层
OSI的物理层规范是有关传输介质的特性标准,这些规范通常也参考了其他组织制定的标准。
连接头、帧、帧的使用、电流、编码及光调制等都属于各种物理层规范中的内容。
物理层常用多个规范完成对所有细节的定义。示例:Rj45,802.3等。
*/
public class Demo5 {
}
InetAddress类
package com.qianfeng.test;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Demo6 {
public static void main(String[] args) throws UnknownHostException {
//IP地址 :java面向对象后形成的类InetAddress
//获取自己的主机
InetAddress inetAddress1 = InetAddress.getLocalHost();
System.out.println(inetAddress1.getHostName());//LAPTOP-47K4STIG
System.out.println(inetAddress1.getHostAddress());//192.168.124.1
//获取网络上任意一台主机
InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress2.getHostName());//www.baidu.com
System.out.println(inetAddress2.getHostAddress());//220.181.112.244
}
}
网络通信之Socket通信:UDP客户端
package com.qianfeng.test;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
* 网络通信之Socket通信:TCP/UDP
*
* TCP与UDP通信的区别:
* TCP UDP
* 1.是建立在连接的基础上 建立在非连接的基础上
* 2.安全性更高 安全性低
* 3.传输速度低 速度高
* 4.适合传输数据量大的数据 数据量小的数据
*
* 客户端:(app/浏览器)
* 服务器端:!=主机
*
* 端口号:同一台主机上的每一个服务器都拥有自己的端口号,取值范围(0,65535),常用的端口:80,8080
* 注意点:1.要保证客户端和服务器端的端口号一致 2.要保证同一台主机上的不同服务器端口号不同
*
*先讲解UDP 注意:要先开启服务器端,再开启客户端。
*客户端
*实现过程:
* 1.创建UDP通信的对象--socket对象,对应的类是DatagramSocket(用于UDP通信数据的发送和接收)
* 2.数据的封装--装包(打包),DatagramPacket(数据包,包括相关的属性,数据等)
* 3.发送--调用send方法
* 4.关闭相关资源
*
*/
public class Demo7 {
public static void main(String[] args) throws IOException {
// * 1.创建UDP通信的对象--socket对象,对应的类是DatagramSocket(用于UDP通信数据的发送和接收)
DatagramSocket socket = new DatagramSocket();
// * 2.数据的封装--装包(打包),DatagramPacket(数据包,包括相关的属性,数据等)
/*
* 第一个参数:包的内容
* 第二个:数据的长度
* 第三个:服务器的主机对象
* 第四个:服务器的端口
*/
byte[] buf = "bingbing".getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 20000);//端口与服务器端一致
// * 3.发送--调用send方法
socket.send(packet);
// * 4.关闭相关资源
socket.close();
}
}
网络通信之Socket通信:UDP服务器端
package com.qianfeng.test;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
* 服务器端--接收数据
* 1.创建socket对象,绑定端口
* 2.创建包对象,创建空数组,准备接收传过来的数据
* 3.接收数据
* 4.关闭资源
*/
public class Demo8 {
public static void main(String[] args) throws IOException {
// * 1.创建socket对象,绑定端口
DatagramSocket socket = new DatagramSocket(20000);
// * 2.创建包对象,创建空数组,准备接收传过来的数据
byte[] buf =new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
// * 3.接收数据--当服务器运转起来,这个方法会一直处于监听状态。
socket.receive(packet);
byte[] arr = packet.getData();
System.out.println(new String(arr));
//将数据从包中取出
// * 4.关闭资源
socket.close();
}
}
实现随时发随时收—使用UDP(客户端)
package com.qianfeng.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/*
* 实例:实现随时发随时收---使用UDP
*
* 客户端
*/
public class Demo9 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
//获取字符缓冲流实现从控制台接收数据
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String data = null;
while ((data = bufferedReader.readLine()) != null) {
DatagramPacket packet = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getLocalHost(), 20000);//端口与服务器端一致
//发送
socket.send(packet);
//当用户输入over的时候代表结束
if (data.equals("over")) {
break;
}
}
socket.close();
}
}
实现随时发随时收—使用UDP(服务器端)
package com.qianfeng.test;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
* 服务器端
*/
public class Demo10 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(20000);
//实现不断的接收数据
while (true) {
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
// * 3.接收数据--当服务器运转起来,这个方法会一直处于监听状态.
socket.receive(packet);
//将数据从包中取出
byte[] arr = packet.getData();
String data = new String(arr);
System.out.println(data);
//当用户输入over的时候代表结束
if (data.trim().equals("over")) {
break;
}
}
socket.close();
}
}
TCP客户端
package com.qianfeng.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* TCP:
* 客户端
* 在客户端与服务器端通信的时候,对于客户端既要进行输入又要进行输出,所以在Socket对象的内部就内置了输入流和输出流,
* 当进行数据传输的时候,将数据放入socket对象的内部,将socket对象传到服务器端,相当于在客户端与服务器端建立了一个通道,
* 两端使用同一个socket对象.
*/
public class Demo11 {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.创建Socket对象并绑定服务器的端口和主机地址
Socket socket = new Socket(InetAddress.getLocalHost(), 30000);
//2.准备数据
String data = "BigData1715,你好";
//3.获取Socket对象内部的输出流
OutputStream outputStream = socket.getOutputStream();
//4.将数据写入网络
outputStream.write(data.getBytes());
//接收从服务器回传的信息
InputStream inputStream = socket.getInputStream();
byte[] arr = new byte[103];
// int num = inputStream.read(arr);
// System.out.println(new String(arr,0,num));
int num = 0;
while ((num = inputStream.read(arr)) != -1) {
System.out.println(new String(arr,0,num));
}
//5.关闭资源
//outputStream.close();
socket.close();
}
}
TCP服务器端
package com.qianfeng.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 服务器端:
*/
public class Demo12 {
public static void main(String[] args) throws IOException {
//1.创建ServerSocket对象并绑定端口
ServerSocket serverSocket = new ServerSocket(30000);
//2.接收套接字---socket对象,accept方法会一直处于监听状态
Socket socket = serverSocket.accept();
//3.获取输入流
InputStream inputStream = socket.getInputStream();
//4.将内容写到控制台
byte[] arr = new byte[103];
int num = inputStream.read(arr);
System.out.println(new String(arr,0,num));
// int num = 0;
// while ((num = inputStream.read(arr)) != -1) {
// System.out.print(new String(arr,0,num));
// }
//完成数据的回传
OutputStream outputStream = socket.getOutputStream();
outputStream.write("你好,BigData1715".getBytes());
//5.关闭资源
serverSocket.close();
}
}
TCP实例:实现大小写转换(客户端)
package com.qianfeng.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* TCP实例:实现大小写转换
*客户端
*
*/
public class Demo13 {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.创建Socket对象并绑定服务器的端口和主机地址
Socket socket = new Socket(InetAddress.getLocalHost(), 30001);
//2.准备数据
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
//注意:这里最好使用原始的流
//3.获取socket内部的输入流与输出流
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream,true);//当第二个参数为true的时候会自动刷新,
//当执行println、printf 或 format 方法的时候
String data = null;
while ((data = bufferedReader.readLine()) != null) {
//发送
// outputStream.write(data.getBytes());
// outputStream.flush();
printWriter.println(data);
//接收服务器端的数据
byte[] arr = new byte[100];
int num = inputStream.read(arr);
System.out.println(new String(arr,0,num));
//当用户输入over的时候代表结束
if (data.equals("over")) {
break;
}
}
socket.close();
}
}
TCP实例:实现大小写转换(服务器端)
package com.qianfeng.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 服务器端
*/
public class Demo14 {
public static void main(String[] args) throws IOException {
//1.创建ServerSocket对象并绑定端口
ServerSocket serverSocket = new ServerSocket(30001);
//2.接收套接字---socket对象,accept方法会一直处于监听状态
Socket socket = serverSocket.accept();
//3.获取输入流
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream,true);//当第二个参数为true的时候会自动刷新,
//当执行println、printf 或 format 方法的时候
int num=0;
byte[] arr = new byte[100];
while ((num = inputStream.read(arr)) != -1) {
//打印到控制台
String data = new String(arr,0,num);
System.out.println(data);
//信息回传
//outputStream.write(data.toUpperCase().getBytes());
printWriter.println(data.toUpperCase());
//当用户输入over的时候代表结束
if (data.equals("over")) {
break;
}
}
serverSocket.close();
}
}