网络编程
1.1、概述
地球村:现代科技的发展,缩短了世界的距离
计算机网络:计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程的目的:传播交流信息,进行数据交换,通信
达到效果需要的东西:
-
如何准确的定位网络上的一台主机 192.168.6.55:端口号
-
如何传输数据
1.2、网络通信的要素
实现网络的通信:
-
通信双方的地址
-
IP
-
端口号
-
-
规则(网络通信协议):
http、tcp、udp、
TCP/IP 参考模型
小结:
-
网络编程中有两个主要的问题
-
如何准确的定位到网络中的一个或者多台主机、
-
找到主机之后如何进行通信
-
-
网络编程中的要素
-
IP和端口号
-
网络编程协议(protocol)
万物皆对象
-
1.3、IP
IP地址:inetAddress
-
唯一定位一台网络上的主机
-
本机地址 127.0.0.1
-
IP分类
-
IPv4 / IPv6
-
公网私网
-
公网:互联网
-
私网:局域网
-
-
-
import java.net.InetAddress; import java.net.UnknownHostException; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 13:17 */ //测试IP public class TestInetAddress { public static void main(String[] args) { try { //查询本机地址 InetAddress name1 = InetAddress.getByName("127.0.0.1"); System.out.println(name1); InetAddress name2 = InetAddress.getByName("localhost"); System.out.println(name1); InetAddress localHost = InetAddress.getLocalHost(); System.out.println(localHost); //返回IP地址与计算机所有人 //查询百度 InetAddress name3 = InetAddress.getByName("www.baidu.com"); System.out.println(name3); //常用方法 System.out.println(name3.getAddress()); System.out.println(name3.getHostAddress()); //获得IP System.out.println(name3.getHostName()); //获得域名 System.out.println(name3.getCanonicalHostName()); //获得规范的名字 System.out.println(name3.getClass()); } catch (UnknownHostException e) { e.printStackTrace(); } } }
1.4、端口
端口表示计算机上的一个程序的进程
-
不同的进程有不同的端口号,用来区分软件
-
端口被规定:0-65535
-
TCP/UDP tcp:80;udp:80 单个写一下,端口号不能冲突
-
端口分类
-
公用端口 1~1023
-
http 80
-
http 443
-
ftp 21
-
telent 23
-
-
程序注册端口:1024~49151
-
Tomcat 8080
-
MySql 3306
-
Oracle 1521
-
-
动态、私有:49152~65535 (别用)
-
netstate -ano 查看所有端口 netstate -ano[findstr "5900"] #查看指定端口 tasklist|findstr "5900" #查看指定的端口进程(PID)
-
1.5、通信协议
协议(protocol):约定,
网络通信协议:速率、船速码率、代码结构、传输控制
TCP/IP协议簇
-
TCP:用户传输协议 (打电话)
-
UDP:用户数据报协议 (发短信)
-
IP:网络互联协议
TCP UDP 对比
-
TCP
-
连接、稳定
-
需要连接才能发送
-
三次握手,四次挥手
-
A:请求连接 B:回应 A:建立连接 A:请求断连 B:接收请求 B:询问A确认请求 A:确认请求,断开连接
-
-
C/S
-
传输完成、释放连接、效率低
-
-
UDP
-
不连接、不稳定
-
C/S
-
不需要连接就可以发送
-
DDOS攻击:饱和攻击,使端口拥堵
-
1.6、TCP
发送消息
Client
-
连接服务器 Socket
-
发送消息
代码
package csDemo; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.nio.charset.StandardCharsets; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 15:12 */ public class ClientDemo1 { public static void main(String[] args) { //获得服务器的地址与端口 Socket socket = null; OutputStream os = null; try { InetAddress ServerIP = InetAddress.getByName("127.0.0.1"); int port = 1999; //创建一个socket连接 socket = new Socket(ServerIP, port); //发送消息 os = socket.getOutputStream(); //字节流,所以需要转为Bytes os.write("我是刘正伟".getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { e.printStackTrace(); } finally { if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
Service
-
建立服务的端口 Server
-
等待用户的连接 Accept
-
接受用户消息
代码
package csDemo; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 15:13 */ public class ServiceDemo1 { public static void main(String[] args) { ServerSocket serversocket = null; ByteArrayOutputStream baos = null; InputStream is = null; Socket socket = null; try { //建立服务器端口 serversocket = new ServerSocket(1999); //等待客户端连接 socket = serversocket.accept(); //读取客户端发过来的消息 is = socket.getInputStream(); //管道流 baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int temp; while ((temp = is.read(buffer)) != -1) { //将is读出来的数据放入到缓存区buffer中 baos.write(buffer, 0, temp); } System.out.println(baos); /*StringBuilder sb = new StringBuilder(); int temp = 0; while((temp = is.read())!=-1){ sb.append((char)temp); } System.out.println(sb);*/ } catch (IOException e) { e.printStackTrace(); } finally { try { baos.close(); } catch (IOException e) { e.printStackTrace(); } try { is.close(); } catch (IOException e) { e.printStackTrace(); } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } try { serversocket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
文件上传
客户端
package 传输文件; import java.io.*; import java.net.InetAddress; import java.net.Socket; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 16:43 */ public class ClientDemo { public static void main(String[] args)throws Exception{ //创建一个Socket连接 Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000); //创建一个输出流 OutputStream os = socket.getOutputStream(); //读取文件 FileInputStream fis = new FileInputStream(new File("D:/1.jpg")); //写出文件 byte[] buffer = new byte[1024]; int len; while((len = fis.read(buffer))!=-1){ os.write(buffer,0,len); } //通知服务器,我已经传输完了,让服务器的监听器停止监听 socket.shutdownOutput(); InputStream is = socket.getInputStream(); //接收另一边socket发过来的信息 //确定服务器接收完毕,才能断开连接 ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer2 = new byte[1024]; int temp; while ((temp= is.read(buffer2)) != -1) { baos.write(buffer2, 0, temp); } System.out.println(baos.toString()); //关闭资源 fis.close(); os.close(); socket.close(); } }
服务端
package 传输文件; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 16:49 */ public class ServerDemo { public static void main(String[] args) throws Exception { //chu ServerSocket serverSocket = new ServerSocket(9000); //监听客户端的连接 Socket accept = serverSocket.accept(); //阻塞式监听,会一直等待客户端。 //获取输入流 InputStream is = accept.getInputStream(); //文件输出 FileOutputStream fos = new FileOutputStream(new File("receive.jpg")); byte[] buffer = new byte[1024]; int len; while ((len = is.read(buffer)) != -1) { fos.write(buffer, 0, len); } //通知客户端接收完毕 OutputStream os = accept.getOutputStream(); os.write("我是胡亚莉".getBytes()); //关闭资源 fos.close(); is.close(); accept.close(); serverSocket.close(); } }
Tomcat
服务端
-
自定义
-
Tomcat服务器
客户端
-
自定义
-
浏览器
1.7、UDP
发送消息
发送信息,不需要进行连接
发送端
package UDP; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.nio.charset.StandardCharsets; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 17:37 */ //udp不需要连接服务器, public class udpclient1 { public static void main(String[] args) throws Exception { //建立一个socket服务 DatagramSocket socket = new DatagramSocket(); //建立一个包 InetAddress localhost = InetAddress.getByName("127.0.0.1"); String msg = "胡亚莉,奥里给"; int port = 1000; //把数据加入到包 //数据,起点,终点,地址,端口 DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port); // 发送包 socket.send(packet); //通过socket服务吧 packet包送出去 //关闭流 socket.close(); } }
接收端
package UDP; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 17:51 */ public class udpserver1 { public static void main(String[] args)throws Exception { //开放端口 DatagramSocket socket = new DatagramSocket(1000); //接收数据 byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length); socket.receive(packet); System.out.println(new String(packet.getData(),0,packet.getLength())); socket.close(); } }
循环发送消息 / 循环接受消息
发送消息
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 21:30 */ public class Chat1 { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(8888); while (true) { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String data = reader.readLine(); byte[] datas = data.getBytes(); DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666)); //将数据打包放入packet if (data.equals("bye")){ break; } socket.send(packet);} socket.close(); } }
接收消息
import java.net.DatagramPacket; import java.net.DatagramSocket; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 21:30 */ public class Chat2 { public static void main(String[] args) throws Exception { //打开端口 DatagramSocket socket = new DatagramSocket(6666); //创建一个容器,接收数据 byte[] container = new byte[1024]; while (true) { DatagramPacket packet = new DatagramPacket(container, 0, container.length); socket.receive(packet);//阻塞式接受包裹 byte[] data = packet.getData(); String datas = new String(data, 0, data.length); System.out.println(datas); if (datas.equals("bye")) { break; } } socket.close(); } }
在线咨询(多线程实现)
SendClient
package 咨询____多线程; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 21:54 */ public class SendClient { } class p1 implements Runnable { DatagramSocket socket = null; BufferedReader reader = null; private int fromPORT; private String toIP; private int toPORT; public p1(int fromPORT, String toIP, int toPORT) { this.fromPORT = fromPORT; this.toIP = toIP; this.toPORT = toPORT; try { socket = new DatagramSocket(fromPORT); reader = new BufferedReader(new InputStreamReader(System.in)); } catch (Exception e) { e.printStackTrace(); } } @Override public void run() { while (true) { String data = null; //通过控制台获取数据 try { data = reader.readLine(); } catch (IOException e) { e.printStackTrace(); } byte[] datas = data.getBytes(StandardCharsets.UTF_8); DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPORT)); if (reader.equals("exit")) { break; } try { socket.send(packet); } catch (IOException e) { e.printStackTrace(); } } socket.close(); } }
ReceiveClient
package 咨询____多线程; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 21:56 */ public class ReceiveClient { } class s1 implements Runnable { DatagramSocket socket = null; private int prot; private String name; public s1(int prot, String name) { this.prot = prot; this.name = name; try { socket = new DatagramSocket(prot); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { //创建容器 while (true) { try { byte[] container = new byte[1024]; DatagramPacket packet = new DatagramPacket(container, 0, container.length); //阻塞式接收包裹 socket.receive(packet); byte[] data = packet.getData(); //将接收到包裹 解包转化为 字节流 String datas = new String(data, 0, data.length); //将字节流转化为字符串 System.out.println(name+":"+datas); if (datas.equals("exit")) { break; } } catch (IOException e) { e.printStackTrace(); } } socket.close(); } }
TalkP1
package 咨询____多线程; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 22:45 */ public class TalkP1 { public static void main(String[] args) { //开启两个线程 new Thread(new p1(7777,"localhost",9999)).start(); new Thread(new s1(8888,"胡亚莉")).start(); } }
TalkP2
package 咨询____多线程; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/13 22:47 */ public class TalkP2 { public static void main(String[] args) { new Thread(new p1(5555,"localhost",8888)).start(); new Thread(new s1(9999,"刘正伟")).start(); } }
1.8、URL
同意资源定位符:定位资源的
DNS:域名解析
URLDownload
import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; /** * @version 1.0 * @description:TODO * @Author: * @date :2021/9/14 0:03 */ public class URLDownload { public static void main(String[] args) throws Exception{ //下载地址 URL url = new URL("https://p3.music.126.net/-m3uvfiZbSxTfmAQBsPitQ==/109951166096206163.jpg?param=34y34"); //连接到这个资源 HTTP HttpURLConnection urlConnection =(HttpURLConnection) url.openConnection(); InputStream is = urlConnection.getInputStream(); FileOutputStream fos = new FileOutputStream("Music.jpg"); byte[] buffer = new byte[1024]; int len; while((len = is.read(buffer))!=-1){ fos.write(buffer,0,len); //写出这个数据 } fos.close(); is.close(); urlConnection.disconnect(); } }