网络编程
网络
由点和线构成,表示诸多对象间的相互联系
计算机网络
为实现资源共享和信息传递,通过通信线路连接起来的若干主机(Host)
计算机网络分为:
- 互联网:(Internet)点与点相连
- 万维网:(WWW-World Wide Web)端与端相连
- 物联网:(IoT-Internet of things)物与物相连
- 网络编程:让计算机与计算机之间建立连接、进行通信交流
网络模型
OSI开放式系统互联
第七层:应用层负责文件访问和管理、可靠运输服务、远程操作服务。(HTTP、FTP、SMTP)
第六层:表示层负责定义转换数据格式及加密,允许选择以二进制或ASCII码格式传输
第五层:会话层负责使应用建立和维护会话,使通信在失效时继续恢复通信。(断点续传)
第四层:传输层负责是否选择差错恢复协议、数据流量重用、错误排序重排。(TCP、UDP)
第三层:网络层负责定义能够标识所有网络节点的逻辑地址(IP地址)
第二层:数据链路层在物理层上,通过规程或协议(差错控制)来控制传输数据的正确性。(MAC)
第一层:物理层为设备之间的数据通信提供传输信号和物理介质(双绞线、光导纤维)
通信协议
TCP/IP模型
一组用于实现网络互连的通信协议,将协议分成四个层次:
第四层:应用层负责传送各种最终形态的数据,是直接与用户打交道的层,典型协议是HTTP、FTP等
第三层:传输层负责传送文本数据,主要协议是TCP、UDP协议
第二层:网络层负责分配地址和传送二进制数据,主要协议是IP协议
第一层:网络接口层负责建立电路连接,是整个网络的物理基础,典型的协议包括以太网、ADSL等等
TCP/UDP
TCP协议:传输控制协议
- 是一种面向连接的、可靠的、基于字节流的传输层通信协议。
- 数据大小无限制
- 建立连接的过程需要上次握手,断开连接的过程需要四次挥手
UDP协议:用户数据报协议
- 是一种无连接的传输层协议,提供面向事务的简单不可靠传送服务,每个包的大小64KB
IP与端口号
IP协议:互联网协议地址/国际协议地址
- 分配给互联网设备的数字标签(唯一标识)
IP地址分为两种:
- IPV4:4字节32位整数,并分成4段8位的二进制数,每8位之间用圆点隔开,每8位整数可以转换为一个0~255的十进制整数。
- 格式为:D.D.D.D 例如:255.255.255.255
- IPV6:16字节128位整数,并分成8段十六位进制数,每16位之间用圆点隔开,每16位整数可以转换位一个0~65535的十进制数。
- 格式:X.X.X.X.X.X.X.X
- 例如:FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF
- IPV4的应用分类:
- A类:政府机构,1.0.0.1~126.255.255.254
- B类:中型企业,128.0.0.1~191.255.255.254
- C类:个人用户,192.0.0.1~233.255.255.254
- D类:用于组播,244.0.0.1~239.255.254
- E类:用于实验,240.0.0.1~255.255.255.254
- 回环地址:127.0.0.1,代指本机,一般用于测试使用
- 查看IP命令:ipconfig
- 测试IP命令:ping D.D.D.D
端口号(Port)
端口号:在通信实体上进行网络通讯的唯一标识
端口分类:
- 保留端口:0~1023(用于电脑本身自己设置号了的端口号也被称之为(已知端口)
- 注册端口:1024~49151
- 动态或私有端口:49152~65535(理论上不应该为服务分配这些端口)
常用端口:
- MySQL:3306为默认端口
- Oracle:1521为默认端口
- Tomcat:8080为默认端口
- SMTP:25为默认端口
- Web服务器:80为默认端口
- FTP服务器:21为默认端口
InetAddress类
概念:
- 表示互联网协议IP地址对象,封装了与该IP地址相关的所有信息,并提供获取信息的常用方法
方法:
- public static InetAddress getLocalHost()获得本地主机地址对象
- public static InetAddress getByName(String host)根据主机名称获得地址对象
- public static InetAddress][] getAllByName(String host)获取所有相关地址对象
- public String getHostAddress()获取IP地址字符串
- public String getHostName()获得IP地址主机名
网络编程
Socket编程:
- Socket(套接字)是网络中的一个通信节点
- 分为客户端Socket与服务器ServerSocket
- 通信要求:IP地址+端口号
开发步骤
建立通信连接(会话):
- 创建ServerSocket,指定端口号
- 调用accept等待客户端接入
客户端请求服务器:
- 创建Socket,指定服务器IP+端口号
- 使用输出流,发送请求数据给服务器
- 使用输入流,接受响应数据到客户端(等待)
服务器响应客户端:
- 使用输入流,接收请求数据到服务器(等待)
- 使用输出流,发送响应数据给客户端
TCP的使用:
TCP:方式交流,发送一次后必须对方发送信息后,才能继续发送
//tcp方式 交流,发送一次后必须对方发送信息后,才能继续发送
public class Server {
@SuppressWarnings("all")
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
Socket scoket = serverSocket.accept();
//接受客户端的消息
BufferedReader br = new BufferedReader(new InputStreamReader(scoket.getInputStream()));
String readLine = br.readLine();
System.out.println(readLine);
//向客户端发送信息
PrintStream ps = new PrintStream(scoket.getOutputStream());
ps.println("沝桜菲:君何时到?");
}
}
public class Client {
@SuppressWarnings("all")
public static void main(String[] args) throws IOException {
//创建客户端socket对象,指定服务端电脑ip和端口号
Socket socket = new Socket("10.7.173.96", 8080);
//向服务器发送信息
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("榮十一:卿等吾");
//接收来自服务器的信息
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String readLine = br.readLine();
System.out.println(readLine);
}
}
TCP:无限制交流,可一个用户一直发信息
//tcp无限制交流,可一个用户一直发信息
public class Server {
@SuppressWarnings("all")
public static void main(String[] args)throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept();
new ReceiveThread(socket).start();
Scanner scan = new Scanner(System.in);
PrintStream ps = new PrintStream(socket.getOutputStream());
while (true){
ps.println("沝桜菲:"+scan.next());
}
}
}
public class Client {
@SuppressWarnings("all")
public static void main(String[] args)throws IOException {
Socket socket = new Socket("127.0.0.1",8080);
Scanner scan = new Scanner(System.in);
new ReceiveThread(socket).start();
PrintStream ps = new PrintStream(socket.getOutputStream());
while (true){
ps.println("榮十一:"+scan.next());
}
}
}
public class ReceiveThread extends Thread{
private Socket socket;
public ReceiveThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader br=null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
while (true){
String readLine=null;
try {
readLine = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(readLine);
}
}
}
TCP: 传输视频
public class Client {
@SuppressWarnings("all")
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 8080);
InputStream in = socket.getInputStream();
BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("download.mp4"));
byte [] arr=new byte[1024];
int len;
while ((len=in.read(arr))!=-1){
bw.write(arr,0,len);
}
in.close();
bw.close();
}
}
public class Server {
@SuppressWarnings("all")
public static void main(String[] args)throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept();
FileInputStream in = new FileInputStream("s1.mp4");
OutputStream out = socket.getOutputStream();
byte[] bs=new byte[1024];
int len;
while ((len=in.read(bs))!=-1){
out.write(bs,0,len);
}
in.close();
out.close();
}
}
tcp:群聊
建立群聊,让其他人在此聊天,并且服务端还可以查看到聊天信息:
public class Server {
public static ConcurrentHashMap<InetAddress, Socket> map = new ConcurrentHashMap<>();
@SuppressWarnings("all")
public static void main(String[] args)throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
while (true){
Socket socket = serverSocket.accept();
//获取客户端的IP地址
InetAddress ip = socket.getInetAddress();
map.put(ip,socket);
//创建线程
new ServerThread(socket).start();
}
}
}
public class Client {
@SuppressWarnings("all")
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 8080);
Scanner scan = new Scanner(System.in);
new ReceiveThread(socket).start();
PrintStream ps = new PrintStream(socket.getOutputStream());
while (true){
ps.println("榮十一:"+scan.next());
}
}
}
public class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader br=null;
//接收当前Socket的消息
try {
br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
while (true){
String readLine=null;
try {
readLine= br.readLine();
System.out.println(readLine);
//发送给其他Socket
ConcurrentHashMap<InetAddress, Socket> map = Server.map;
Set<Map.Entry<InetAddress, Socket>> entrySet = map.entrySet();
for (Map.Entry<InetAddress,Socket> entry:entrySet) {
InetAddress key = entry.getKey();
Socket value = entry.getValue();
if (socket.getInetAddress()!=key){
PrintStream ps = new PrintStream(value.getOutputStream());
ps.println(readLine);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class ReceiveThread extends Thread {
private Socket socket;
public ReceiveThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader br=null;
try {
br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
while (true){
String readLine=null;
try {
readLine= br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(readLine);
}
}
}
UDP的使用:
UDP快递送礼
public class Server {
public static void main(String[] args) throws IOException{
//所在城市的快递公司
DatagramSocket socket = new DatagramSocket(8080);
//2.接收的礼物
byte[] bs = new byte[1024];
DatagramPacket packet = new DatagramPacket(bs , bs.length);
socket.receive(packet);
System.out.println(new String(bs).trim());
//3.回礼
byte[] buf = "向日葵一束".getBytes();
packet = new DatagramPacket(buf, buf.length, packet.getSocketAddress());
socket.send(packet);
}
}
public class Client {
//trim()去空格
public static void main(String[] args) throws IOException {
//所在城市的快递公司
DatagramSocket socket = new DatagramSocket();
//1.发快递
//礼物
byte[] bs = "满天星一束~~".getBytes();
//数据报包 -- 快递包裹
DatagramPacket packet = new DatagramPacket(bs, bs.length, InetAddress.getByName("127.0.0.1"), 8080);
//发送
socket.send(packet);
//4.接收礼物
byte[] buf = new byte[1024];
packet = new DatagramPacket(buf , buf.length);
socket.receive(packet);
System.out.println(new String(buf).trim());
}
}
UDP:一对一聊天
public class Client01 { /** * 知识点:一对一 */ public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(7070); new SendThread(socket,"榮十一","127.0.0.1",8080).start(); new ReceiveThread(socket).start(); } }
public class Client02 { public static void main(String[] args)throws IOException { DatagramSocket socket = new DatagramSocket(8080); new SendThread(socket,"雅惠","127.0.0.1",7070).start(); new ReceiveThread(socket).start(); } }
public class ReceiveThread extends Thread{ private DatagramSocket socket; public ReceiveThread(DatagramSocket socket) { this.socket = socket; } @Override public void run() { while (true){ byte[] bs=new byte[1024]; DatagramPacket packet = new DatagramPacket(bs, bs.length); try { socket.receive(packet); System.out.println(new String(bs).trim()); } catch (IOException e) { e.printStackTrace(); } } } }
public class SendThread extends Thread{ private DatagramSocket socket; private String name; private String ip; private int port; public SendThread(DatagramSocket socket, String name, String ip, int port) { this.socket = socket; this.name = name; this.ip = ip; this.port = port; } @Override public void run() { Scanner scan = new Scanner(System.in); while (true){ byte [] buf=(name+":"+scan.next()).getBytes(); DatagramPacket p; try { p= new DatagramPacket(buf, buf.length,InetAddress.getByName(ip),port); socket.send(p); } catch (IOException e) { e.printStackTrace(); } } } }
HTTP的使用:
HTTP查询快递
public class Test01 {
/**
* 知识点:http
* 需求:查询快递
*/
@SuppressWarnings("all")
public static void main(String[] args)throws IOException {
//网络接口
String urlStr="http://www.kuaidi100.com/query?type=哪一种快递&postid=订单号";//如韵达快递的type=yunda
//创建网络接口对象
URL url = new URL(urlStr);
//获取HttpURLConnection对象
HttpURLConnection coon = (HttpURLConnection) url.openConnection();
//设置
coon.setRequestMethod("GET");//设置请求方式
coon.setConnectTimeout(5000);//设置连接超时时间
coon.setReadTimeout(5000);//设置读取超时时间
//获取响应状态码
int responseCode = coon.getResponseCode();
if (responseCode==200){
BufferedReader br = new BufferedReader(new InputStreamReader(coon.getInputStream()));
char[] cs = new char[1024];
int len;
while ((len= br.read(cs))!=-1){
System.out.println(new String(cs,0,len));
}
}else if (responseCode==404){
System.out.println("页面丢失");
}
}
}
HTTP下载图片:
public class Test02 {
public static void main(String[] args)throws IOException {
/**
* 知识点:http
* 下载图片
*
*/
//网络接口
String urlStr="https://img2.baidu.com/it/u=1964941983,3152712063&fm=26&fmt=auto&gp=0.jpg";
//创建网络接口的对象
URL url=new URL(urlStr);
//获取HttpURLConnection对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置
conn.setRequestMethod("GET");//设置请求方式
conn.setConnectTimeout(5000);//设置连接超时时间
conn.setReadTimeout(5000);//设置读取时间超时
//获取响应状态码
int responseCode = conn.getResponseCode();
if (responseCode==HttpURLConnection.HTTP_OK){
//获取响应中的数据
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("课堂.jpg"));
byte[] bs=new byte[1024];
int len;
while ((len=bis.read(bs))!=-1){
bos.write(bs,0,len);
}
bos.close();
bis.close();
}else if (responseCode==HttpURLConnection.HTTP_NOT_FOUND){
System.out.println("页面丢失");
}
}
}
if (responseCode==HttpURLConnection.HTTP_OK){
//获取响应中的数据
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("课堂.jpg"));
byte[] bs=new byte[1024];
int len;
while ((len=bis.read(bs))!=-1){
bos.write(bs,0,len);
}
bos.close();
bis.close();
}else if (responseCode==HttpURLConnection.HTTP_NOT_FOUND){
System.out.println("页面丢失");
}
}
}