导读:
1.网络:
将不同区域的计算机群和外部设备通过通信设备组成的网络集群,按大小可分为局域网,城域网,广域网(互联网)。
2.地址:
ip地址:确定网络上的一个绝对地址,位置->相当于房子的地址
3.端口号:
用于区分计算机软件->相当于房子的房门号 ->2个字节 0-65535,共65536个端口号
(1)在同一个协议下端口号不可重复,不同协议下可以重复
(2)1024以下的尽量避免使用
4.资源定位:
URL统一资源定位符:URI->统一资源
5.数据的传输
(1)协议:
1)TCP:类似电话,三次握手,面向连接,安全可靠,效率低下,基于字节流
2)UDP:类似短信 ,面向无连接,效率高,数据可能丢失
(2)传输:
1)先封装
2)后拆封
相关类:
1.InetAddress(封装计算机的IP地址和DNS,没有端口) ->InetSocketAddress
(1)方法:
getHostAddress()返回IP地址
getHostName()返回域名/本机为计算机名
2.URL
由四部分组成:协议 ->存放资源的主机域名 ->端口号->资源文件名
(1)创建:
URL url=new URL(String url);绝对路径
URL url=new URL(URL context,String url);相对路径
(2)方法:
URL url=new URL("https://piaofang.maoyan.com/dashboard?date=2019-01-02");
System.out.println("协议:"+url.getProtocol());
System.out.println("存放资源的主机域名:"+url.getHost());
System.out.println("端口号:"+url.getPort());
System.out.println("资源文件名:"+url.getFile());
System.out.println("参数:"+url.getQuery());
System.out.println("锚点:"+url.getRef());
3.TCP:ServerSocket ->Socket通信
(1)面向连接:请求:相应 request-》response
(2)Socket编程:
1) SocketServer(int port) ->创建服务器端+指定端口
2)接收客户端连接-》阻塞式 -》accept();返回一个Socket对象,表示一条管道
4.UDP:DatagramSocket ->DatagramPacket
(1)客户端:
1)创建客户端:DatagramSocket +指定端口
2)准备数据 : 字节数组
3)打包: DatagramPacket + 服务器地址+端口
4)发送:
5)释放资源:
(2)服务器端:
1)创建服务端: DatagramSocket +指定端口
2)准备接收容器: 字节数组 封装 DatagramPacket
3)封装成包:-》接收数据
4)分析:
5)释放资源:
上代码了解一下:
1.InetAddress
1 package com.etc; 2 3 import java.net.InetAddress; 4 import java.net.InetSocketAddress; 5 import java.net.UnknownHostException; 6 7 8 public class InetDemo { 9 public static void main(String[] args) throws UnknownHostException { 10 11 /*InetAddress ip=InetAddress.getLocalHost();两种方法均可以获得指定的主机名对应的IP地址*/ 12 InetAddress ip=InetAddress.getByName("逐梦青空"); 13 //本机名称 14 System.out.println(ip.getHostName()); 15 //获取的是 IPv4 地址 16 System.out.println(ip.getHostAddress()); 17 System.out.println("****************"); 18 19 InetSocketAddress id=new InetSocketAddress("逐梦青空",8080); 20 21 System.out.println(id.getAddress()); 22 System.out.println(id.getHostString()); 23 System.out.println(id.getHostName()); 24 //以上三种方法均可以获得对应ip地址下的主机名 25 System.out.println(id.getPort()); 26 } 27 }
效果截图:
2.InetSocketAddress
1 package com.etc; 2 3 import java.net.InetSocketAddress; 4 /* 5 * 套接字socket,包含端口并将其加以封装 6 * InetSocketAddress isa=new InetSocketAddress(String hostname,int port); 7 */ 8 public class InetSocketDemo { 9 public static void main(String[] args) { 10 //不仅可以封装ip地址和DNS,还可以封装port即端口号 11 InetSocketAddress isa=new InetSocketAddress("逐梦青空",8080); 12 System.out.println("端口号:"+isa.getPort()+";地址: "+isa.getAddress()+";主机名:"+isa.getHostName()); 13 14 } 15 }
效果截图:
3.URL
1 package com.etc; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStreamReader; 8 import java.io.OutputStreamWriter; 9 import java.net.URL; 10 11 public class URLDemo { 12 13 public static void main(String[] args) throws IOException { 14 15 URL url=new URL("https://photo.fengniao.com/f_15.html"); 16 System.out.println("协议:"+url.getProtocol()); 17 System.out.println("存放资源的主机域名:"+url.getHost()); 18 System.out.println("端口号:"+url.getPort()); 19 System.out.println("资源文件名:"+url.getFile()); 20 System.out.println("参数:"+url.getQuery()); 21 System.out.println("锚点:"+url.getRef()); 22 23 //利用openStream()方法返回输入流资源 24 BufferedReader bf=new BufferedReader(new InputStreamReader(url.openStream(),"utf-8")); 25 //信息重组以文件形式返回 26 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("蜂鸟.html"),"utf-8")); 27 //利用循环读取输入流信息 28 String msg=null; 29 while((msg=bf.readLine())!=null) { 30 bw.append(msg); 31 bw.newLine(); 32 33 } 34 //关闭流 35 bf.close(); 36 bw.close(); 37 } 38 39 }
效果截图:
4.UDP
(1)客户端
1 package com.test; 2 3 import java.io.IOException; 4 import java.net.DatagramPacket; 5 import java.net.DatagramSocket; 6 import java.net.InetSocketAddress; 7 import java.net.SocketException; 8 9 /* 10 * 1)创建客户端:DatagramSocket +指定端口 11 * 2)准备数据 : 字节数组 12 * 3)打包: DatagramPacket + 服务器地址+端口 13 * 4)发送: 14 * 5)释放资源: 15 */ 16 public class Myclient { 17 18 public static void main(String[] args) throws IOException { 19 //创建客户端 20 DatagramSocket client=new DatagramSocket(6666); 21 //准备数据 : 字节数组 22 String msg="我很喜欢敲代码!"; 23 byte[] by=msg.getBytes(); 24 //打包: DatagramPacket + 服务器地址+端口 25 //DatagramPacket(byte buf[], int offset, int length, InetAddress address, int port) 26 DatagramPacket packet=new DatagramPacket(by,by.length,new InetSocketAddress("逐梦青空",8888)); 27 //发送: 28 client.send(packet); 29 //释放资源 30 client.close(); 31 } 32 33 }
(2)服务器端
1 package com.test; 2 3 import java.io.IOException; 4 import java.net.DatagramPacket; 5 import java.net.DatagramSocket; 6 import java.net.SocketException; 7 8 /* 9 * 1)创建服务端: DatagramSocket +指定端口 10 * 2)准备接收容器: 字节数组 封装 DatagramPacket 11 * 3)封装成包:-》接收数据 12 * 4)分析: 13 * 5)释放资源: 14 */ 15 public class Myserver { 16 17 public static void main(String[] args) throws IOException { 18 //创建服务端 19 DatagramSocket server=new DatagramSocket(8888); 20 //准备接收容器 1M 21 byte[] by=new byte[1024*1024]; 22 //包 23 DatagramPacket packet=new DatagramPacket(by,by.length); 24 //接收数据 25 server.receive(packet); 26 //分析: 27 byte[] data=packet.getData(); 28 int len=packet.getLength(); 29 System.out.println(new String(data,0,len)); 30 //释放资源 31 server.close(); 32 } 33 34 }
效果截图:
5.TCP
(1)客户端:
1 package com.socket; 2 3 import java.io.DataInputStream; 4 import java.io.IOException; 5 import java.net.Socket; 6 import java.net.UnknownHostException; 7 //接收数据 8 public class Client { 9 10 public static void main(String[] args) throws UnknownHostException, IOException { 11 /*创建客户端 Socket(String hostname,int port) 12 若服务器端未开启,则抛出 13 Exception in thread "main" java.net.ConnectException: Connection refused: connect 14 的异常*/ 15 Socket client=new Socket("localhost",8888); 16 DataInputStream in=new DataInputStream(client.getInputStream()); 17 System.out.println(new String(in.readUTF())); 18 } 19 20 }
(2)服务器端:
1 package com.socket; 2 3 import java.io.DataOutputStream; 4 import java.io.IOException; 5 import java.net.ServerSocket; 6 import java.net.Socket; 7 8 /** 9 * 必须先启动服务器端然后在启动客户端连接 10 * 发送数据 11 */ 12 public class Server { 13 14 public static void main(String[] args) throws IOException { 15 int i=0; 16 //创建服务器端+指定端口 ServerSocket(int port) 17 ServerSocket server=new ServerSocket(8888); 18 //接收客户端连接-》阻塞式 -》accept();返回一个Socket对象,表示一条管道 19 //多个客户端连接 20 while(true) { 21 Socket socket=server.accept(); 22 i++; 23 System.out.println("第"+i+"个客户端已连接!"); 24 String msg="客户端连接成功,欢迎使用!"; 25 26 DataOutputStream out=new DataOutputStream(socket.getOutputStream()); 27 //信息写入,数据发送 28 out.writeUTF(msg); 29 out.flush(); 30 } 31 } 32 33 }
效果截图:
socket编程深入,利用多线程实现简单聊天室:
(1)客户端:
1 package com.test; 2 3 4 import java.io.IOException; 5 import java.net.Socket; 6 import java.net.UnknownHostException; 7 8 //创建客户端 发送数据+接收数据 9 public class Client { 10 public static void main(String[] args) throws UnknownHostException, IOException { 11 Socket client=new Socket("localhost",8899); 12 13 //发送数据 14 SendThread s=new SendThread(client); 15 Thread t1=new Thread(s); 16 t1.start(); 17 18 //接收数据 19 ReceiveThread r=new ReceiveThread(client); 20 Thread t2=new Thread(r); 21 t2.start(); 22 23 } 24 }
(2)接收数据线程与发送数据线程:
1 package com.test; 2 3 import java.io.DataInputStream; 4 import java.io.IOException; 5 import java.net.Socket; 6 7 public class ReceiveThread implements Runnable{ 8 private DataInputStream in; 9 public ReceiveThread(Socket client) { 10 try { 11 in=new DataInputStream(client.getInputStream()); 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } 15 } 16 //接收来自客户端的数据 17 public void dealMsgFromClient() { 18 try { 19 in.readUTF(); 20 } catch (IOException e) { 21 e.printStackTrace(); 22 } 23 } 24 25 @Override 26 public void run() { 27 while(true) { 28 dealMsgFromClient(); 29 } 30 } 31 32 }
1 package com.test; 2 3 import java.io.BufferedReader; 4 import java.io.DataOutputStream; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 import java.net.Socket; 8 //发送数据线程 9 public class SendThread implements Runnable{ 10 11 private BufferedReader console; 12 private DataOutputStream out; 13 14 public SendThread() { 15 console=new BufferedReader(new InputStreamReader(System.in)); 16 } 17 18 public SendThread(Socket client) { 19 this(); 20 try { 21 out=new DataOutputStream(client.getOutputStream()); 22 } catch (IOException e) { 23 e.printStackTrace(); 24 } 25 } 26 27 //从控制台接收数据然后发送数据 28 public void dealMsg() { 29 try { 30 //接收数据 31 String msg=console.readLine(); 32 if(msg!=null && !msg.equals("")) { 33 //发送数据 34 out.writeUTF(msg); 35 out.flush(); 36 } 37 } catch (IOException e) { 38 e.printStackTrace(); 39 } 40 41 } 42 @Override 43 public void run() { 44 while(true) { 45 dealMsg(); 46 } 47 } 48 }
(3)服务器端:
1 package com.test; 2 3 import java.io.IOException; 4 import java.net.ServerSocket; 5 import java.net.Socket; 6 import java.util.ArrayList; 7 import java.util.List; 8 9 10 //创建服务器端 11 public class Server { 12 //定义一个集合用于存放所有的客户端角色 13 public static List<ClientThread> list=new ArrayList<ClientThread>(); 14 15 public static void main(String[] args) throws IOException { 16 ServerSocket server=new ServerSocket(8899); 17 //获取与客户端的连接 18 Socket client=server.accept(); 19 20 //加入客户端线程 21 ClientThread ct=new ClientThread(client); 22 //将客户端角色添加入集合中 23 list.add(ct); 24 25 Thread c1=new Thread(ct); 26 c1.start(); 27 } 28 29 //在这里声明一个方法用于对所有集合中的客户端角色进行操作 30 public static void sortClients(ArrayList<ClientThread> listClients) { 31 32 } 33 }
(4)客户端多线程:
1 package com.test; 2 3 import java.io.DataInputStream; 4 import java.io.DataOutputStream; 5 import java.io.IOException; 6 import java.net.Socket; 7 8 //客户端线程,使一个客户对应一条道路 9 public class ClientThread implements Runnable{ 10 private DataInputStream in; 11 private DataOutputStream out; 12 13 14 public ClientThread(Socket client) { 15 try { 16 in=new DataInputStream(client.getInputStream()); 17 out=new DataOutputStream(client.getOutputStream()); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 23 //对数据进行处理: 先读后写 24 private void dealMsg() { 25 try { 26 String msg= in.readUTF(); 27 System.out.println("接收到客户端数据:"+msg); 28 out.writeUTF(msg); 29 out.flush(); 30 } catch (IOException e) { 31 e.printStackTrace(); 32 } 33 } 34 35 @Override 36 public void run() { 37 while(true) { 38 dealMsg(); 39 } 40 } 41 }
效果截图: