网络:可以交换数据、共享资源的东西,必须由多台计算机组成
服务器:计算能力较高的计算机
邮件服务器:功能类似于通信基站的
web服务器:网站的服务器
Apache Tomcat
大部分网站都遵循http协议
C/S(客户端/服务器)端的应用程序:比如需要下载软件才能打开的
B/S(浏览器/服务器)端的应用程序:只需要浏览器就可以打开
IP地址:InetAdress
唯一标识网络上的每一台计算机
32位,由4个8位二进制组成
127.0.0.1:本机 localhost
IP地址= 网络地址+主机地址
网络地址:标记正在使用的网段的
主机地址:标记正在使用的主机的
IP地址分类:
ipv4/ipv6
ipv4: 127.0.0.1,四个字节组数。0~255, 42亿~
ipv6: fe80::bc1c:57b0:8fbc:7c26%4, 128位 8个无符号整数!abcde
2001:0bb2:aaaa:2432:ddc4:2343:fdc3:4324
公网(互联网)——私网(局域网)
ABCD类地址
192.168.xx.xx,专业给组织内部使用的
查本机的IP: ipconfig
测试网络是否通畅:ping 目标IP地址(例如:ping 192.168.1.20)
//测试IP public class TestInetAddress { public static void main(String[] args) { try { //查询本机地址 InetAddress inetAddress = InetAddress.getByName("127.0.0.1"); System.out.println(inetAddress); InetAddress inetAddress1 = InetAddress.getByName("localhost"); System.out.println(inetAddress1); InetAddress inetAddress3 = InetAddress.getLocalHost(); System.out.println(inetAddress3); //查询网站ip地址 InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com"); System.out.println(inetAddress2); //常用方法 System.out.println(inetAddress2.getAddress()); System.out.println(inetAddress2.getCanonicalHostName());//规范的名字 System.out.println(inetAddress2.getHostAddress());//ip System.out.println(inetAddress2.getHostName());//域名,或自己的电脑名字 } catch (UnknownHostException e) { e.printStackTrace(); } } }
端口表示计算机上的一个程序的进程:
不同的进程,不同的端口号!用来区分软件!
被规定0~65535
TCP、UDP: 65535*2 tcp: 80,udp: 80,单个协议下,端口号不能冲突
端口分类:
公有端口:0~1023
程序注册端口:1014~49251,分配用户或者程序
动态、私有:49152~65535
netstat -ano #查看所有端口 netstat -ano|findstr "5900" #查看指定端口 tasklist|findstr "8696" #查看指定进程 Ctrl+shift+esc
import java.net.InetSocketAddress; public class TestInetSocketAddress { public static void main(String[] args) { InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080); InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost", 8080); System.out.println(inetSocketAddress); System.out.println(inetSocketAddress2); System.out.println(inetSocketAddress.getAddress()); System.out.println(inetSocketAddress.getHostName());//地址 System.out.println(inetSocketAddress.getPort());//端口 } }
协议:约定、契约
网络通讯协议:速率,传输码率,代码结构,传输控制……
应用层:(支持网络运用的层次)HTTP(超文本传输协议):所有的www都遵循此协议
协议:规则
表示层:
会话层:
传输层:数据传输()TCP:连接的协议
网络层:路由选择(选择最合适路径传输数据)
数据链路层:数据链路的连接(如:通过数据链路传输包的过程)
物理层:数据传输的介质:(如:电缆)
TCP/IP协议簇:实际上是一组协议(运输层)
TCP:用户传输协议(打电话)
连接,稳定
三次握手
四次挥手
最小需要三次,保证稳定连接! A:你愁啥? B:瞅你咋地? A:干一场! A:我要走了! B:你真的要走了吗? B:你真的真的要走了吗? A:我真的要走了!!
客户端、服务端
传输完成,释放连接,效率低
UDP:用户数据报协议(发短信)
Socket:接口
Socket先输出再输入,ServerSocket 先输入再输出
客户端
通过Socket链接服务器
发送消息
import java.io.*; import java.net.*; //客户端 public class TcpClientDemo01 { public static void main(String[] args) { Socket socket = null; OutputStream os = null; try { //1.要知道服务器的地址 InetAddress serverIP = InetAddress.getByName("127.0.0.1"); int post = 9998; //2.创建一个socket连接 socket = new Socket(serverIP,post); //3.发送消息IO流 os = socket.getOutputStream(); os.write("你好,欢迎学习狂神说Java".getBytes()); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException 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(); } } } } }
服务器
建立服务的端口ServerSocket
等待用户的连接,通过accept
接收用户的消息
import java.io.*; import java.net.*; //服务端 public class TcpServerDemo01 { public static void main(String[] args) { ServerSocket serverSocket = null; Socket socket = null; InputStream inputStream = null; ByteArrayOutputStream byteArrayOutputStream = null; try { //1.我得有一个地址 serverSocket = new ServerSocket(9998); //2.等待客户端连接过来 socket = serverSocket.accept(); //3.读取客户端的消息 inputStream = socket.getInputStream(); //管道流 byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len=inputStream.read(buffer))!=-1){ byteArrayOutputStream.write(buffer,0,len); } System.out.println(byteArrayOutputStream.toString()); /* byte[] buffer = new byte[1024]; int len; while ((len=inputStream.read(buffer))!=-1){ String s = new String(buffer, 0, len); System.out.println(s); } */ } catch (IOException e) { e.printStackTrace(); }finally { //关闭资源 if (byteArrayOutputStream != null){ try { byteArrayOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (inputStream != null){ try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } if (serverSocket != null){ try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
服务器端代码
import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class TcpServerDemo02 { public static void main(String[] args) throws IOException { //1、创建服务 ServerSocket serverSocket = new ServerSocket(9000); //2、监听客户端链接 Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接 //3、获取输入流 InputStream is = socket.getInputStream(); //4、文件输出 FileOutputStream fos = new FileOutputStream("received.jpeg"); byte[] buffer = new byte[1024]; int len; while ((len = is.read(buffer)) != -1){ fos.write(buffer,0,len); } //通知客户端我已经接收完毕了 OutputStream outputStream = socket.getOutputStream(); outputStream.write("我已经接收完毕!".getBytes()); //关闭资源 fos.close(); is.close(); socket.close(); serverSocket.close(); }
客户端代码
import java.io.*; import java.net.InetAddress; import java.net.Socket; public class TcpClientDemo02 { public static void main(String[] args) throws IOException { //1、创建一个socket链接 Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000); //2、创建一个输出流 OutputStream os = socket.getOutputStream(); //3、读取文件流 FileInputStream fs = new FileInputStream(new File("src/biteCat.jpeg")); //4、写出文件流 byte[] buffer = new byte[1024]; int len; while((len = fs.read(buffer)) != -1){ os.write(buffer,0,len); } //通知服务器已经结束了 socket.shutdownOutput();//我已经传输完了 //接收服务端传来的消息 InputStream inputStream = socket.getInputStream(); byte[] buffer2 = new byte[1024]; int len2; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ((len2 = inputStream.read(buffer2)) != -1){ baos.write(buffer2,0,len2); } System.out.println(baos.toString()); //5、关闭资源 baos.close(); fs.close(); os.close(); socket.close(); } }
服务端
客户端
发送端
import java.io.IOException; import java.net.*; //不需要链接服务器 public class UdpClientDemo01 { public static void main(String[] args) throws IOException { //1、建立一个socket DatagramSocket socket = new DatagramSocket(); //2、建立一个包 String msg = "你好啊!服务器"; //发送给谁 InetAddress localhost = InetAddress.getByName("localhost"); int port = 9090; //参数分别为:发送的消息,数据的起始长度,发送的地址,端口号 DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port); //发送包 socket.send(packet); //关闭流 socket.close(); } }
接收端
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; //要等待客户端的链接 public class UdpServerDemo01 { public static void main(String[] args) throws IOException { //开放端口 DatagramSocket socket = new DatagramSocket(9090); //接收数据包 byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);//接收 socket.receive(packet);//阻塞接收 //控制台输出数据包 System.out.println(packet.getAddress().getHostAddress()); //String里面的参数为byte数组,起始位置,末尾位置(长度) System.out.println(new String(packet.getData(),0,packet.getLength())); //关闭连接 socket.close(); } }
发送端
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.*; public class UpdSenderDemo01 { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(8888); //准备数据,从控制台读取System.in BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); while(true){ String msg = reader.readLine(); byte[] data = msg.getBytes(); //准备封装发送包 DatagramPacket sendPacket = new DatagramPacket(data, data.length, new InetSocketAddress("localhost",6666)); //发送 socket.send(sendPacket); if(msg.equals("bye")){ break; } } //关闭流 socket.close(); } }
接受端
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UpcReceiverDemo01 { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(6666); while(true){ //准备接收包裹 byte[] container = new byte[1024]; DatagramPacket receivedPacket = new DatagramPacket(container,0,container.length); socket.receive(receivedPacket); //阻塞式接收包裹 //断开连接 byte[] data = receivedPacket.getData(); //此处的Length选用receivedPacket的Length,若选用data的Length,可能会变成1024,并没有进行动态生成长度 String receiveMsg = new String(data,0,receivedPacket.getLength()); System.out.println(receiveMsg); if(receiveMsg.equals("bye")){ break; } } //关闭流 socket.close(); } }
TalkSend类
package com.chat; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException; public class TalkSend implements Runnable { DatagramSocket socket = null; //准备数据,从控制台读取System.in BufferedReader reader = null; private int fromPort; private String toIp; private int toPort; public TalkSend(int fromPort, String toIp, int toPort) { this.fromPort = fromPort; this.toIp = toIp; this.toPort = toPort; try{ socket = new DatagramSocket(fromPort); //准备数据,从控制台读取System.in reader = new BufferedReader(new InputStreamReader(System.in)); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while(true){ try{ String msg = reader.readLine(); byte[] data = msg.getBytes(); //准备封装发送包 DatagramPacket sendPacket = new DatagramPacket(data, data.length, new InetSocketAddress(this.toIp,this.toPort)); //发送 socket.send(sendPacket); if(msg.equals("bye")){ break; } }catch (Exception e ){ e.printStackTrace(); } } //关闭流 socket.close(); } }
TalkReceive
package com.chat; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class TalkReceive implements Runnable { DatagramSocket socket = null; private int port; private String msgFrom; public TalkReceive(int port,String msgFrom) throws IOException { this.port = port; this.msgFrom = msgFrom; try { this.socket = new DatagramSocket(this.port); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while(true){ try { //准备接收包裹 byte[] container = new byte[1024]; DatagramPacket receivedPacket = new DatagramPacket(container,0,container.length); socket.receive(receivedPacket); //阻塞式接收包裹 //断开连接 byte[] data = receivedPacket.getData(); //此处的Length选用receivedPacket的Length,若选用data的Length,可能会变成1024,并没有进行动态生成长度 String receiveMsg = new String(data,0,receivedPacket.getLength()); System.out.println( msgFrom + ":" + receiveMsg); if(receiveMsg.equals("bye")){ break; } } catch (IOException e) { e.printStackTrace(); } } //关闭流 socket.close(); } }
测试:老师和学生对话
TalkStudent
public class TalkStudent { public static void main(String[] args) { //开启两条线程 new Thread(new TalkSend("localhost",7777,9999)).start(); new Thread(new TalkReceive(8888,"老师")).start(); } }
TalkTeacher
public class TalkTeacher { public static void main(String[] args) { new Thread(new TalkSend("localhost",5555,8888)).start(); new Thread(new TalkReceive(9999,"学生")).start(); } }
Uniform Resource Locator
统一资源定位符:定位资源的,定位互联网的
协议://ip地址:端口/项目名/资源
import java.io.*; import java.net.*; public class UrlDown { public static void main(String[] args) throws Exception { //1.下载地址 URL url = new URL(""); //2.连接到这个资源 HTTP HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream inputStream = urlConnection.getInputStream(); FileOutputStream fos = new FileOutputStream(""); byte[] bytes = new byte[1024]; int len; while ((len=inputStream.read(bytes))!=-1){ fos.write(bytes,0,len);//写出这个数据 } fos.close(); inputStream.close(); urlConnection.disconnect();//断开连接 } }