java学习笔记之网络编程

网络编程

一.网络通信协议

  1.网络协议

    不同的操作系统,不同的硬件设备上都能够联网,是因为互联网设计规定了一套标准,这套标准就被称为网络协议,网络协议规定了网络传输的格式,速率和方式;

  2.TCP/IP协议

    是一组协议:HTTP ,FTP,SMTP,DNS

    TCP:传输控制协议

    IP:互联网协议

    TCP/IP协议的分层:

      应用层:上位机应用程序,比如说qq,用来产生数据和显示数据

      传输层:端口号   加入一些标志位,保证数据传输的准确性

      网络层:ip地址  用来寻找对方电脑在哪里

      链路层:网卡驱动  用来发送或接收数据

  3. IP地址:

    在一个网络中ip地址可以唯一标识一台电脑。

     ipv4:xxx.xxx.xxx.xxx     点分十进制  32个二进制位来描述ip:21个亿

     ipv6:128个二进制位来描述ip:无数个

  4.端口号:

    就是联网的每一个应用程序制定一个编号,编号可以唯一标识一个应用程序

    1-65535

    1-1024:系统使用

    1024-6000:系统保留

    >6000自己使用

    一台电脑的应用程序想和另一台电脑的一个程序通信  必须知道ip地址和端口号

二.UDP 和TCP协议

  1.udp协议:用户数据报协议

    面向无连接的协议,两台电脑在通信之前不需要建立连接,发送端只管发送,不会关心接收端是否已经收到,或者接收端是否存在

    优点:数据传输速度快,效率高

    缺点:数据安全性不高,数据容易丢失;

    应用场景:电话会议,视频直播,网络会议---->实时性

  2.tcp协议:传输控制协议 

    两台电脑在通信之前必须建立连接(三次握手),每次发送完数据,都会有一个反馈信息。

    优点:数据安全性高,可靠性强

    缺点:传输数度慢,效率低

    应用场景:密码管理,金融支付,理财系统

三.InetAddress类

 1 /*
 2      * InetAddress类用来描述一台电脑的信息:ip地址,计算机名和其他信息
 3      * public  static InetAddress getLocalHost();可以获取本地电脑主机的信息
 4      * public  static InetAddress getByName(String host);可以获取任意电脑主机的信息
 5      */
 6     public static void main(String[] args)throws Exception {
 7         //获取本地电脑主机的信息
 8         InetAddress  address=InetAddress.getLocalHost();
 9         //使用getHostAddress()方法获取本地的ip地址
10         String  ip=address.getHostAddress();
11         //使用getHostName()方法获取本地主机名
12         String  hostName=address.getHostName();
13         //-------------------------getByName()方法的使用---------------------------------
14         //获取指定指定主机的电脑信息
15         InetAddress  bdAddress=InetAddress.getByName("www.baidu.com");//这里参数可以是网址,ip地址,和主机名
16         //获取百度的ip地址
17         String  baiDuIp=bdAddress.getHostAddress();
18         System.out.println("百度的IP地址是:"+baiDuIp);
19         //获取百度的主机名
20         String baiDuHostName=bdAddress.getHostName();
21         System.out.println("百度的主机名是:"+baiDuHostName);
22     }

四.UDP编程

  1.使用udp实现发送端的编写:

 1 public class SendDemo {
 2 
 3     public static void main(String[] args) throws IOException {
 4         //1:建立一个码头,该程序有一个对外连接的窗口
 5         /*
 6          * 套接字
 7          */
 8         DatagramSocket ds = new DatagramSocket();
 9         //2:准备要发送的货物:数据
10         byte[] bytes = "hello udp!!!!".getBytes();
11         
12         //3:准备一个集装箱,将货物取装入集装箱
13         /*
14          * 参1:你要发送的数据
15          * 参2:你要发送的字节长度
16          * 参3: 表示接收端的ip地址
17          * 参4: 表示接收端的端口号
18          */
19         //"192.168.65.103" --->InetAddress
20         InetAddress address = InetAddress.getByName("192.168.65.255");
21         DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, 8888);
22         //4: 发送集装箱
23         ds.send(dp);
24         //5:关流
25         ds.close();
26     }
27 
28 }

  2.使用udp协议实现接收端编写:

 1 public class ReceiveDemo {
 2 
 3     public static void main(String[] args) throws IOException {
 4         //1:建立一个码头,并绑定端口
 5         DatagramSocket ds = new DatagramSocket(8888);
 6         //2:准备一个空的集装箱,用来接收数据
 7         /*
 8          * 参1:表示要接收的数据存放在哪个字节数组
 9          * 参2:表示要接收的数据长度
10          */
11         byte[] bytes = new byte[1024]; //"hello" ip 和端口
12         DatagramPacket dp = new DatagramPacket(bytes, bytes.length);    
13         //3:接收数据
14         ds.receive(dp); //如果没有接收到数据,则该方法阻塞    
15         //4:从集装箱中获取数据
16         byte[] data = dp.getData(); //"hello"
17         int length = dp.getLength();
18         //获取发送端的ip
19         InetAddress address = dp.getAddress();
20         String ip = address.getHostAddress();
21         //5:打印接收到的数据
22         System.out.println(ip+":"+new String(data,0,length));
23     }
24 
25 }

五.TCP编程

  交互流程图:

  图片上传案例:

     客户端的编写:

 1 public class ClientDemo {
 2     public static void main(String[] args) throws IOException {
 3         //1:获取文件的输入流(读)
 4         FileInputStream fis = new FileInputStream("a.jpg");
 5         
 6 //        BufferedInputStream bufis = new BufferedInputStream(fis);
 7         
 8         //2:获取套接字的输出流
 9         InetAddress address = InetAddress.getLocalHost();
10         Socket socket = new Socket(address, 9999);
11         OutputStream os = socket.getOutputStream();
12 //        BufferedOutputStream bufos = new BufferedOutputStream(os);
13         
14         //3:将从文件输入流读取的数据写到套接字的输出流
15         byte[] bytes = new byte[1024];
16         int len = 0;
17         while((len = fis.read(bytes)) != -1){
18             os.write(bytes,0,len);
19         }
20         //关闭输出流
21 //        socket.close();  //输入流和输出流都关闭
22         socket.shutdownOutput();  //值关闭输出流
23         //--接收反馈信息 
24         //3.1获取套接字的输入流
25          InputStream is = socket.getInputStream();
26         //3.2 读取数据
27          len = is.read(bytes);
28         System.out.println(new String(bytes,0,len));
29         //4:关流
30         socket.close();
31         fis.close();
32     }
33 
34 }

      服务器端的编写:

 1 public class ServerDemo {
 2     public static void main(String[] args) throws IOException {
 3         //1:获取套接字的输入流
 4         ServerSocket sSocket = new ServerSocket(9999);
 5         Socket cSocket = sSocket.accept();
 6         InputStream is = cSocket.getInputStream();
 7         
 8         //2:获取文件的输出流
 9         FileOutputStream fos = new FileOutputStream("D:\Server\a.jpg");
10         /*
11          * while循环要想结束必须read方法读取-1,在普通文件的读取中,读取到文件末尾就能-1
12          * 但是套接字没有文件末尾,所以不能返回-1
13          * 
14          * 如何让服务器读取到-1?
15          *  只要让客户端把输出流进行关闭
16          */
17         //3:将从套接字输入流读取的数据写入文件的输出流
18         byte[] bytes = new byte[1024];
19         int len = 0;
20         while((len = is.read(bytes)) != -1){
21             fos.write(bytes, 0, len);
22         }
23         //--在这里给客户端反馈
24         //3.1 获取套接字的输出流
25         OutputStream os = cSocket.getOutputStream();
26         //3.2 发送反馈信息
27         os.write("上传成功啦!".getBytes());
28         //4:关流
29         fos.close();
30         cSocket.close();
31         sSocket.close();
32     }
33 }

   多图片上传案例:

   客户端:

 1 public class ClientDemo {
 2 
 3     public static void main(String[] args) throws IOException {
 4         //1:获取文件的输入流(读)
 5         FileInputStream fis = new FileInputStream("a.jpg");
 6         
 7 //        BufferedInputStream bufis = new BufferedInputStream(fis);
 8         
 9         //2:获取套接字的输出流
10         InetAddress address = InetAddress.getLocalHost();
11         Socket socket = new Socket(address, 10086);
12         OutputStream os = socket.getOutputStream();
13 //        BufferedOutputStream bufos = new BufferedOutputStream(os);
14         
15         //3:将从文件输入流读取的数据写到套接字的输出流
16         byte[] bytes = new byte[1024];
17         int len = 0;
18         while((len = fis.read(bytes)) != -1){
19             os.write(bytes,0,len);
20         }
21         //关闭输出流
22 //        socket.close();  //输入流和输出流都关闭
23         socket.shutdownOutput();  //值关闭输出流
24         //--接收反馈信息 
25         //3.1获取套接字的输入流
26          InputStream is = socket.getInputStream();
27         //3.2 读取数据
28          len = is.read(bytes);
29         System.out.println(new String(bytes,0,len));
30         //4:关流
31         socket.close();
32         fis.close();
33     }
34 
35 }

  服务器端:

 1 public class ServerDemo {
 2     public static void main(String[] args) throws IOException {
 3         ServerSocket sSocket = new ServerSocket(10086);
 4         //有多少个请求,accept就执行多少次
 5         while(true){
 6             Socket cSocket = sSocket.accept();
 7             //每来一个请求,就创建一个线程,去处理请求
 8             Thread t = new Thread(new MyRunnable(cSocket));
 9             t.start();
10         }
11     }
12 }

   多线程:

 1 public class MyRunnable implements Runnable {
 2     private Socket cSocket;
 3     
 4     public MyRunnable(Socket cSocket) {
 5         this.cSocket = cSocket;
 6     }
 7 
 8     public MyRunnable() {
 9     }
10     //a.txt --->a(2).txt
11     @Override
12     public void run() {
13         try {
14             //1: 获取套接字的输入流
15             InputStream is = cSocket.getInputStream();
16             long time = System.currentTimeMillis();
17             
18             //2:获取文件的输出流
19             FileOutputStream fos = new FileOutputStream("D:\Server\"+time+".jpg");
20             
21             //3:将从套接字输入流读取的数据写入文件的输出流
22             byte[] bytes = new byte[1024];
23             int len = 0;
24             while((len = is.read(bytes)) != -1){
25                 fos.write(bytes, 0, len);
26             }
27             System.out.println("while之后");
28             
29             //--在这里给客户端反馈
30             //3.1 获取套接字的输出流
31             OutputStream os = cSocket.getOutputStream();
32             //3.2 发送反馈信息
33             os.write("上传成功啦!".getBytes());
34             
35             //4:关流
36             fos.close();
37             cSocket.close();
38         } catch (Exception e) {
39         }
40     }
41 
42 }
原文地址:https://www.cnblogs.com/xuzhaocai/p/8094866.html