目录 :
1 ) . 网络编程(概述)
2 ) . 网络编程(网络模型)
3 ) . 网络编程(IP地址)
4 ) . 网络编程(TCP和UDP)
5 ) . 网络编程(Socket)
6 ) . 网络编程(Udp-发送端)
7 ) . 网络编程(Udp-接收端)
8 ) . 网络编程(Udp-键盘录入方式数据)
9 ) . 网络编程(Udp-聊天)
10 ) . 网络编程(TCP-传输)
11 ) . 网络编程(TCP-练习)
一
.
网络编程(概述)
1 ) . 简述 :网络通讯要素详解, IP地址的发展, 端口号的区分,以及常用的传输协议
1.1 网络模型
[1] OSI参考模型
[2] TCP/IP参考模型
1.2 网络通讯要素
[1] IP地址
[2] 端口号
[3] 传输协议
1.3 图解通讯方式 :
2 ) . 理解 :
2.1 IP地址 -->如同你的快递明确的送货地址 -->指唯一标识位置
2.2 端口 : -->如送你的快递明确的收货人手机号 --> 指唯一标识人
2.3 协议: --> 如送你的快递明确的收获方式,双方都得知道 -->指相互约定好的规则
3 ) . 物理端口与逻辑端口的区别?
3.1 物理端口是看到的摸得着的端口,例 : 网线接口
3.2 逻辑端口是虚拟的端口,例如 QQ程序
4 ). 数据传输软件(QQ)的流程?
4.1 寻找对方计算机IP
4.2 寻找对方应用程序上的逻辑端口 -->端口是网络应用程序通过数字对自己进行表示的方式
4.3 判断通讯规则是否为同一协议 --> 国际组织定义了通用协议
TCP/IP ,是通讯的规则
5 ) . IP地址(四段)的发展 --.>子网掩码的出现 --> IP地址(六段) :
5.1 当计算机越来越普及的时候,IP不够用了,为了解决此问题,根据一个区域只给一个IP, 这个IP就是子网掩码
5.2 再到后来IP又不够用了,于是出现了IPV6 ,也就是 6段的IP地址
小结 : 区域子网掩码(区域IP) --> 个人IP地址
6 ) . IP(四段)与IP(六段)的区别?
6.1 ipV4 的地址都是数字,而ipV6不仅包含数字还包含字母
7 ) . 端口号的区分 :
7.1 0-1024的端口号被系统所保留,用来给相关应用程序
7.2 0-65535 的端口号 随意选择,只是 0-1024端口号尽量别用,留给系统分配
8 ). 常用端口号:
8.1 web : 80
8.2 Tomcat : 8080
8.3 mySql : 3306
9 ). 常用的传输协议
9.1 TCP/IP
9.2 UDP
10 ) . 心得 :
10.1 网络编程是 单机版 --> 网络版的递进
10.2 数据通讯的原理就是数据传输
10.3 主机地址(IP地址)是一个计算机在互联网 上的唯一标识
10.4 当我们双方没有同一协议时,是不能完成通讯的,有些机密组织有自己的通讯协议
小结 :
1. IP地址 --> 端口号 -->协议
2. IP地址分为四段,每一段的最大值是2553. 特殊的IP地址 : 本地回环地址 : 127.0.0.1 ,可以用来在dos窗口内输入 ping 127.0.0.1 看反馈来 测试网卡,若拼通则正常
4. 局域网中会出现IP冲突的问题,而广域网则不会
5. 但凡是应用程序,都需要有数字标识,这数字标识就是端口号
二.
网络编程(网络模型)
1 ) . OIS模型图解 :
![]()
2 ) TCP/IP图解:
![]()
3 ) . 相关常见协议 :
3.1 应用层协议 :
[1] HTTP (Hyper Text Transfer Protocol) : 超文本传输协议
[2] HTTPS (Hyper Text Transfer Protocol) : 超文本传输协议安全
[3] FTP (File Transfer Protocol) : 文件传输协议
[4] NFS (Network File System): 网络文件系统
[5] SMTP (Simple Message Transfer Protocol) ; 简单邮件传输协议
3.2 传输层协议 :
[1] TCP (Transmission Control Protocol) : 传输控制协议
[2] UDP (User Datagram Protocol) : 用户数据报协议
[3] SPX (Sequenced Packet Exchange protocol): 序列分组交换协议
3.3 网际层协议
[1] IP (Internet Protocol) : 互联网协议
[2] IPX (Internet Packet eXchange): 以太网所用协议之一
小结 :
1. 无论是OSI模型还是TCP/IP模型,每个层次都有自己的协议,也就是通讯规则
三.
网络编程(IP地址)
1 ) . 复习网络通讯要素:
1.1 IP地址 :
[1] 网络中设备的标识
[2] 不易记忆,可用主机名
[3] 本地回环地址: 127.0.0.1 主机名: localhost
1.2 端口号 :
[1] 用于标识进程的逻辑地址,不同进程的标识
[2] 有效端口 : 0~65535 ,其中0~1-024系统使用或保留端口
1.3 传输协议:
[1] 通讯的规则
[2] 常见协议 : TCP,UDP
2 ) . IP地址解析 :
3 ) . Demo:
/*本章讲述 :[1] InetAddress.getLocalHost(); : 此静态方法可实例化IP的对象[2] getHostAddress() : 获取本机地址[3] getHostName() ; 获取本机地址名称[4] InetAddress.getByName("10.1.4.79"); 通过IP获取其IP地址和主机名称小结; 先有对象,而后对象调方法*/class IpDemo{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]) throws UnknownHostException{/* InetAddress lhost = InetAddress.getLocalHost(); //实例化一个IP地址对象String ipAdress = lhost.getHostAddress() ; //获取本机地址String ipName =lhost.getHostName() ; //获取本机地址名称sop(ipName.toString()+":"+ipAdress.toString()); //输出本机名称和地址IP *///---------------通过IP地址获取任意主机IP对应的名称/* InetAddress ipName = InetAddress.getByName("10.1.4.79"); //通过IP获取地址名称和主机名称sop(ipName.getHostAddress());sop(ipName.getHostName());*/sop(ipName.getHostAddress());sop(ipName.getHostName());}}小结 :
1. 事务非常负责时可将其封装为对象以此简化,因为面向对象的特点是复杂程度简单化2. 一个IP有多个服务器地址 ,一个地址只能对应一个IP
四.
网络编程(TCP和UDP)
1 ) . 概念简述:、
1.1 UDP : 面向无连接,是用户数据报协议
【1】 将数据及源和目的封装成数据包中,不需要建立连接
【2】 每个数据报的大小在限制在64K内
【3】因无连接,是不可靠协议
【4】不需要建立连接,因此速度快
1.2 TCP :面向连接,是传输控制协议
【1】建立连接,形成传输数据的通道
【2】在连接中进行大数据量传输
【3】通过三次握手完成连接,是可靠协议
【4】必须建立连接,因此效率会低
2 ) . 相关案例:
2.1 UDP : 聊天软件,屏幕共享,网络视频会议
2.2 TCP : 下载软件,语音通话
2.3 可通过数据是否可不完整性来判断是UDP还是TCP,还可通过是否可不同步/同步的方式来判断是UDP还是TCP
3 ) . UDP和TCP的区别:
3.1 UDP如同短信,TCP如同电话
3.2 UDP是异步的,TCP是需同步的
3.3 UDP是可丢数据的,TCP是不可丢数据的
3.4 UDP是高效传输的,TCP是低效完整传输的
3.5 TCP内部是需要三次握手协议的,UDP是不需要的
小结 :
1. UDP如如同古时的写信,TCP如同现代的线上线下物流体系2. 三次握手协议是 ,一次请求,两次反馈
五
.
网络编程(Socket)
1 ) . 简述 :
1.1 Socket就是为网络服务提供的一种机制
1.2 通信的两端都有Socket
1.3 网络通信其实就是Socket间的通信
1.4 数据在两个Socket见通过IO传输
小结 :
1. 所谓的网络编程就是Socket(插座)编程2. 370的插座能插370针脚的CPU
3. socket通讯也可形象说是两个码头间的通讯,依靠(IO)船只进行货物(数据)的传输
4.
六.
网络编程(Udp-发送端)
1 ) . Demo:
/*本章讲述 : 通过udp传输方式,将一段文字数据发送出去思路:1.建立udpsocket服务2.提供数据,并将数据封装到数据包中3.通过socket服务的发送功能,将数据包发送出去4.关闭资源*/class UdpSend{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]) throws Exception{//1.创建udp服务,通过DatagramSocket对象DatagramSocket ds =new DatagramSocket();//2.确定数据,并封装成数据包 ; DatagramPaket(byte[] buf,int length,InetAdress adress ,int port)byte[] buf ="udp go me lai le".getBytes();DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.152.1"),1000);//3.通过socket服务,将已有的数据包发送出去,通过send方法ds.send(dp);//4.关闭资源ds.close();}}
2 ) . 流程 : 有服务,有数据,发送,而后关闭资源
小结 :
1. 码头于码头(Socket)之间输送货物,标准(TCP)是无损坏,方式(IO)是 船运,码头是socket,传输协议是 TCP /UDP , 传输方式是IO流
七.
网络编程(Udp-接收端)
1 ) . Demo:
/*本章讲述 : 通过udp传输方式,将一段文字数据发送出去思路:1.建立udpsocket服务2.提供数据,并将数据封装到数据包中3.通过socket服务的发送功能,将数据包发送出去4.关闭资源方法:[1] DatagramSocket() : 初始化socket服务[2] DatagramPacket() ; 初始化数据包[3] send(); //数据发送方法*/class UdpSend{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]) throws Exception{//1.创建udp服务,通过DatagramSocket对象DatagramSocket ds =new DatagramSocket();//2.确定数据,并封装成数据包 ; DatagramPaket(byte[] buf,int length,InetAdress adress ,int port)byte[] buf ="udp go me lai le".getBytes();DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.152.1"),10000);//3.通过socket服务,将已有的数据包发送出去,通过send方法ds.send(dp);//4.关闭资源ds.close();}}/*需求 : 定义一个应用程序,用于接受UDP协议传输的数据并处理思路:1.定义udpSocket服务 -->通常会监听一个端口,其实就是给这个接受网络应用程序定义数字表示,方便于明确哪些数据过来该应用程序可以处理2.定义一个数据包,因为要存储接收到的字节数据,因为数据包对象具有更多功能可提取字节数据中的不同数据信息3.通过socket服务的receive方法可将收到的数据存入已定义好的数据包中4.通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上5.关闭资源方法:[1] DatagramSocket() : 初始化socket服务[2] DatagramPacket() ; 初始化数据包[3] receive(); //数据接收方法[4]getAddress(); 获取地址[5] getHostAddress(); 获取主机地址[6] getData() ; 获取数据*/class UdpReceive{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]) throws Exception{//1.创建udp socket,建立端点,并定义端口号DatagramSocket ds = new DatagramSocket(10000);while(true) //在这里循环判定说明其接收服务一直开启{//2.定义数据包,欲用存储数据byte[] buf =new byte[1024];DatagramPacket dp =new DatagramPacket(buf,buf.length);//3.通过服务的receive方法将受到数据存入数据包中ds.receive(dp); //其是阻塞式方法,到这里定会停止//4通过数据包的方法获取其中的数据String reAdd = dp.getAddress().getHostAddress();int rePo = dp.getPort();String str =new String(dp.getData(),0,dp.getLength());sop(reAdd+":::"+str+":::"+rePo);}//5.关闭资源//ds.close(); //关闭,是因为让服务一直开启}}
小结 :
1. 发送端可采用随机端口号,但接收端一定得自定义端口号,不然数据不知发哪去2. 一个发送端一个接收端,这是两个程序,需要开两个cmd程序
八
.
网络编程(Udp-键盘录入方式数据)
1 ) . Demo:
/*本文讲述 :一个接收端接收.一个发送端发送,不断发送,不断接收[1] IO流[2] sorcket服务*/import java.io.*;//发送端class UdpSend2{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]) throws Exception{DatagramSocket ds =new DatagramSocket();BufferedReader br =new BufferedReader(new InputStreamReader(System.in));String line=null;while((line=br.readLine())!=null){if(line.equals("886"))break;byte[] buf =line.getBytes();DatagramPacket dp =new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.152.1"),1000);ds.send(dp);}ds.close();}}//接收端class UdpReceive2{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]) throws Exception{DatagramSocket ds =new DatagramSocket(1000);while(true){byte[] buf =new byte[1024];DatagramPacket dp =new DatagramPacket(buf,buf.length);ds.receive(dp);String adre = dp.getAddress().getHostAddress();String str =new String(dp.getData(),0,dp.getLength());sop(adre+"::"+str);}}}
小结 :
1. 一个网段里边有两个端口不可用,一个是0 (网络地址),一个是255(广播地址) ,可通过广播实现群聊
九
.
网络编程(Udp-聊天)
1 ) . Demo:
/*本文讲述 :需求 : 编写一个聊天程序 -->分析 : 有收数据的部分和发数据的部分,这两部分同时执行,因此用到多线程技术 ,一个线程专门用来收,一个线程专门用来发*/import java.io.*;import java.lang.*;//发送端class UdpSend implements Runnable{private DatagramSocket ds;public UdpSend(DatagramSocket ds){this.ds =ds;}public void run(){try{BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); //实例化一个键盘输入流String line=null;while((line=br.readLine())!=null){if(line.equals("886"))break;byte[] buf = line.getBytes(); //数据转化为Byte类型DatagramPacket dp =new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.217.1"),1000); //打包数据ds.send(dp); //发送数据}}catch(Exception e){throw new RuntimeException("传输数据失败");}}}//接收端class UdpReceive implements Runnable{private DatagramSocket ds;public UdpReceive(DatagramSocket ds){this.ds =ds;}public void run(){try{while(true){byte[] buf =new byte[1024]; //定义临时存储容器DatagramPacket dp =new DatagramPacket(buf,buf.length); //接收包ds.receive(dp); //数据放入接收包String ad = dp.getAddress().getHostAddress(); //获取其发送端的本地地址String str =new String(dp.getData(),0,dp.getLength()); //获取数据部分并转化为String类型System.out.println(ad+"::"+str);}}catch(Exception e){throw new RuntimeException("传输数据失败");}}}//主类class ChatDemo{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]) throws Exception{DatagramSocket sendSocket =new DatagramSocket();DatagramSocket receiveSocket =new DatagramSocket(1000);UdpSend us =new UdpSend(sendSocket);UdpReceive ur = new UdpReceive(receiveSocket);new Thread(us).start();new Thread(ur).start();}}
小结 :
1. 聊天程序通过多线程的方式实现,一个线程掌控发数据,一个线程掌握接数据
十.
网络编程(TCP-传输)
1 ) . 简述 :
1.1 Socket和ServerSocket
1.2 建立客户端和服务端
1.3 建立连接后,通过Socket中的IO流进行数据的传输
1.4 关闭socket
1.5 同样,TCP也可通过多线程实现客户端和服务端的两个独立的应用程序
2 ) . Demo:
/*本文讲述 :需求 : 演示TCP传输 ,客户端向服务端发送一条信息须知 : 1.TCP分客户端和服务端 ,客户端对应的对象是Socket,服务端对应的对象是ServerSocket*/import java.io.*;import java.lang.*;/*通过查阅Socket对象,发现在该对象建立时,就可以去连接指定主机,解析 : 因为TCP是面向连接的,因此在建立socket服务室,就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输步骤:1.创建Socket服务,并指定要连接的主机和端口2. 获取socket服务中的输出流用来发送数据3. 关闭服务*///客户端class TcpSocket{//主方法public static void main(String args[]) throws Exception{Socket sc =new Socket ("192.168.217.1",10000); //初始化客户端的socket服务,并指定目的主机和端口OutputStream is = sc.getOutputStream(); //获取socket服务中的输出流用来发送数据is.write("TCPSocket to going".getBytes()); //向流内写入数据sc.close(); //关闭服务}}/*需求 : 定义断点接收数据并打印在控制台上服务端:1.建立服务端的socket服务: ServerSocket();,并监听一个端口2.获取连接过来的客户端的对象 : 通过ServerSocket的accept的方法,没有连接便会等,因此这个方法是阻塞式的3.客户端若发来数据,那么服务端要使用对应的客户端的对象并获取到该客户端对象的读取流来读取发过来的数据并打印在控制台4.关闭服务端(可选)*///服务端class TcpServerSocket{//主方法public static void main(String args[]) throws Exception{ServerSocket ss =new ServerSocket(10000); //建立服务端的socket并监听一个端口Socket sc = ss.accept(); //获取已连接过来的客户端的对象InputStream in = sc.getInputStream(); //获取其输入流来获取数据byte[] buf = new byte[1024]; //临时存储容器int len = in.read(buf); //数据读出String ip = sc.getInetAddress().getHostAddress(); //获取其连接过来的客户端对象的IP地址System.out.println(ip+".......come"); //输出客户端地址System.out.println(new String(buf,0,len)); //输出发过来的数据sc.close(); //关闭客户端的资源ss.close(); //关闭服务端的资源}}
4 .Demo:
/*本文讲述 : 演示TCP传输的客户端和服务端的互访需求 : 客户端给服务端发送数据,服务端收到后,给客户端反馈信息客户端:1.建立socker服务,指定要连接的主机和端口2.获取socket流中的输出流,将数据写到该流中3,获取socker流中的输入流,将服务端反馈的数据获取到,并打印4.关闭客户端资源*/import java.io.*;import java.lang.*;//客户端class TcpSocket{public static void main(String args[]) throws Exception{Socket s= new Socket("192.168.217.1",1000); //初始化客户端对象,并指定主机地址和端口OutputStream ou= s.getOutputStream(); //获取输出流输出数据ou.write("服务端的哥们,你好".getBytes());InputStream is = s.getInputStream(); //获取输入流接受反馈的数据byte[] buf =new byte[1024];int len = is.read(buf);System.out.println(new String(buf,0,len));s.close(); //关闭资源}}//服务端class TcpServerSocket{public static void main(String args[]) throws Exception{ServerSocket ss = new ServerSocket(1000); //初始化服务端对象,并指定连接的端口Socket s = ss.accept(); //进行连接获取其连接对象InputStream is = s.getInputStream(); //获取其连接对象的输入流,用来输出数据String ssAdd = s.getLocalAddress().getHostAddress(); //获取其连接对象的地址System.out.println(ssAdd+"......come");byte[] buf =new byte[1024];int len =is.read(buf);System.out.println(new String(buf,0,len));OutputStream ou = s.getOutputStream(); //获取其连接对象的输出流,用来反馈数据Thread.sleep(1000); //测试: 等待ou.write("客户端,你好,俺服务端收到了".getBytes()); //写入反馈数据s.close(); //关闭客户端资源ss.close(); //关闭服务端资源}}
4 ) .UDP与TCP
4.1 UDP有发送端和接收端 ,使用同一个类 DatagramSocket ,分不同的方法使用
4.2 TCP有客户端和服务端,使用两个类Socket和ServerSocket区分使用
小结 :
1. UDP与TCP最大的不同就是 UDP是面向无连接,而TCP是面向连接,因而导致的方法使用的不同
2. 客户端与服务端的对话要求 : 1. 有俩端口 2. 客户端有输出流输出数据,有输入流获取反馈数据 ; 服务端有输入流接受数据,有输出流反馈数据
十一.
网络编程(TCP-练习)
1 ) . Demo:完整版 -->做一个文本转换服务器
/*本文讲述 : 完整版[1]开发常用对象[2]TCP常见问题需求 : 建立一个文本转换服务器描述 : 客户端给服务器发送文本,服务器会将文本转成大写返回客户端,而且客户端可不断地进行文本转换,当客户端输入ver时,转换结束分析:客户端: 既然是操作设备上的数据,那么就可以用到IO技术,并按照IO的操作规律来思考源:键盘录入目的:网络设备,网络输出流操作的是文本数据,因此可选字符流,想提高效率,又可加入缓冲步骤:1.建立服务2.获取键盘录入3.将数据发送给服务端4.服务端接受数据之后返回大写数据5.结束,关资源服务端:源:socket读取流目的:socket输出流都是文本,装饰;总结 :现象:客户端和服务端都在莫名的等待的原因?因为客户端和服务端都有阻塞式方法,这些方法没有读到结束标记,就会一直等,从而导致两端都等待*/import java.io.*;//客户端class TcpSocket{public static void main(String args[]) throws Exception{//定义客户端端口Socket sk =new Socket("192.168.217.1",1000);//定义读取键盘数据的流对象BufferedReader br =new BufferedReader(new InputStreamReader(System.in));//定义目的,将数据写入到Socket输出流,发给服务端BufferedWriter bwOut =new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));//定义一个socket读取流,读取服务端返回的大写信息BufferedReader brInt =new BufferedReader(new InputStreamReader(sk.getInputStream()));String line=null;while((line=br.readLine())!=null){if(line.equals("over"))break;bwOut.write(line);bwOut.newLine();bwOut.flush();String str = brInt.readLine();System.out.println("TcpSocket:"+str);}sk.close();}}//服务端class TcpServerSocket{public static void main(String args[]) throws Exception{ServerSocket ss =new ServerSocket(1000);Socket s = ss.accept();String Ad = s.getInetAddress().getHostAddress();System.out.println(Ad+"connect.........");//读取socket读取流中的数据BufferedReader br =new BufferedReader(new InputStreamReader(s.getInputStream()));//目的,socket输出流,将大写数据写入到socket输出流,并发送给客户端BufferedWriter bw =new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));String line=null;while((line=br.readLine())!=null){bw.write(line.toUpperCase());bw.newLine(); //字符流需要换行为结束符bw.flush(); //字符流需要刷新才能刷出数据}s.close();ss.close();}}
2 ). Demo: 简约版 -->做一个文本转换服务器
/*本文讲述 :需求 : 建立一个文本转换服务器 , 与上个功能一样,只是简化版替换:[1] PrintStream 替换了之前的BufferedWriter bwOut =new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));bwOut.newLine();bwOut.flush();因为PrintStream类中的方法自带了刷新和换行因此不需要这些了*/import java.io.*;//客户端class TcpSocket{public static void main(String args[]) throws Exception{//定义客户端端口Socket sk =new Socket("192.168.217.1",1000);//定义读取键盘数据的流对象BufferedReader br =new BufferedReader(new InputStreamReader(System.in));//定义目的,将数据写入到Socket输出流,发给服务端PrintStream brOut =new PrintStream(sk.getOutputStream(),true); //通过 printStream代替掉我们的手动刷新等共//定义一个socket读取流,读取服务端返回的大写信息BufferedReader brInt =new BufferedReader(new InputStreamReader(sk.getInputStream()));String line=null;while((line=br.readLine())!=null){if(line.equals("over"))break;brOut.println(line);String str = brInt.readLine();System.out.println("TcpSocket:"+str);}sk.close();}}//服务端class TcpServerSocket{public static void main(String args[]) throws Exception{ServerSocket ss =new ServerSocket(1000);Socket s = ss.accept();String Ad = s.getInetAddress().getHostAddress();System.out.println(Ad+"connect.........");//读取socket读取流中的数据BufferedReader br =new BufferedReader(new InputStreamReader(s.getInputStream()));//目的,socket输出流,将大写数据写入到socket输出流,并发送给客户端PrintStream brOut =new PrintStream(s.getOutputStream(),true);String line=null;while((line=br.readLine())!=null){brOut.println(line.toUpperCase());}s.close();ss.close();}}
小结 : 客户端向服务端发送请求,服务端获取客户端对象并连接,接收客户端的数据,然后反馈给客户端数据