`

黑马程序员——网络编程

 
阅读更多

                          ------- android培训java培训、期待与您交流! ----------

 

网络编程基础知识

1.Socket
         网络编程.  底层的基本的实现. UDP ,TCP
2. 网络基本常识.
        1. ip 地址:网络中计算机的唯一标识. IPv4 32位二进制. 4个字节,无符号的. 表示2(32)个 40亿. 

                          如:192.168.10.1
        2. 端口:通过ip地址可以找到互联网中指定的计算机主机,如果想要进行计算机之间的数据传输,程序                

                       和程序之间进行数据的传输. 端口有范围的,0~65535 之间. 端口在系统中是唯一的,如果一个程  

                       序占用了一个端口,其他程序就不能再用了. 不过程序的结束后,端口会释放,重新使用.

                       0~1024 端口,系统端口,不建议使用. 80 http  21ftp 8080       
3. 域名
         早期的时候我们想要访问互联网的是通过ip:端口号访问互联网,由于比较难记的原因,采用单词来代替

         ip 地址.如:域名:
                                    http://www.baidu.com:80 
                                    http: 超文本传输协议, 超文本...
                                    www   万维网. 
          4. 网络传输协议
                      IP 地址可以访问互联网中指定的计算机, 通过端口号,可以找到指定的应用程序. 网络应用程要

                      进行数据的传输. 数据在传输时,就会遵守一个规则,这个规则就是所谓的互联网的传输协议。

                      他有主要有两种协议:UDP、TCP。

                      UDP(User datagram protocol):用户数据报协议
                      特点: 传输数据时,将数据封装为数据报包, 一个包最大是64k,发送发不需要确认接收方是否在

                               线. 数据有可能丢失,它是一种不可靠的协议.由于发送数据时,不需要确认接收方, 所以速

                               度快.
                      总结: 数据被打包(64k),不可靠,速度快
                      主要是:视频、屏幕广播、视频会议
                                    实时性,很高但是不适合文件的传输.不能保证数据的可靠性...
                      TCP(Transmission control protocol)
                      特点:该协议,会通过3次握手,建立一个连接通道, 通过通道进行数据的传输的. 是可靠的协议,而                  

                      如何保证可靠性? 传输数据时,如果数据丢失,重发数据,保证数据的完整性。但是速度相对于

                      UDP稍慢.适合文件传输。

         常见的命令:
                     ipconfig  查看本机ip 地址
                     ipconfig  /all
                     ping ip地址|主机名  测试网络连接.
                     ping 127.0.0.1  拼本机.
                     ping localhost
3. InetAddress
                     ip地址是一类事物.在java 就被封装为了一个类.这个类就是InetAddress
4.java 的UDP 实现.
                     针对udp协议的实现...
                     设计专业的类来支持udp
            |---DatagramPacket
                     表示数据报包.
                     构造函数: DatagramPacket(byte[] buf, int length)
                     构造 DatagramPacket,用来接收长度为 length 的数据包。
                     DatagramPacket(byte[] buf, int length, InetAddress address, int port)
                     构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
            |---DatagramSocket
                     发送和接收数据报包.
                     send(DatagramPacket packet); 发送数据报包
                     receive(DatagramPacket packet); 接收数据报包.
                     close(); 关闭socket 释放资源.
5.java 的tcp 实现.  
                     针对tcp 协议的实现...
                     特点: 通过三次握手建立连接通道. 可靠的,速度稍慢(相对于UDP).
                     即使传输数据,数据丢失也会重发保证数据的完整性,和可靠性.
                    1. 客户端
                             Socket
                    2. 服务端.
                              ServerSocket
                              C/S  客户端/服务器   模式.
                                                   cf cs    手机端...
                              B/S  浏览器/服务器    模式.
                                                   qq客户端...   
                                                   客户端和服务端建立连接,可以通信. 


 

UDP案例1发送一句话:

发送端:
public class SendDemo1 {
           public static void main(String[] args) throws IOException {
                         System.out.println("udp 发送端... ");
                         // 1. 数据.
                         String mess = "hello,world";
                         // 字符串->字节 编码.
                         byte[] datas = mess.getBytes();
                         // 2. 数据的长度.
                         int length = datas.length;
                         // 3. 目的地. 接收数据的ip
                         InetAddress ip = InetAddress.getByName("192.168.15.10");
                         // 4. 目的地的端口.
                         int port = 5000;
                         // 5. 封装数据. 数据报包.
                         DatagramPacket packet = new DatagramPacket(datas, length, ip, port);
 
                         // 6. 发送数据报包.
                         DatagramSocket socket = new DatagramSocket();
                         socket.send(packet);
 
                         // 7. 关闭socket. 释放资源.
                         socket.close();
         }
}

 

接收端:
public class ReceiveDemo1 {
               public static void main(String[] args) throws IOException {
                          System.out.println("udp 接收端启动");
                          // 1.创建DatagramPakcet -> 存储发送端发送的数据的.
                          DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
                          // 2.创建DatagrameSocket-> 接收数据报包的.
                          DatagramSocket socket = new DatagramSocket(5000);
 
                          // 3.使用对象的专业方法 receive 接收数据报包.
                          // 接收完数据, 数据都被存储到了packet 中.
                          socket.receive(packet);
 
                           // 4. 通过packet 获取数据.
                           byte[] datas = packet.getData();
 
                           String ip = packet.getAddress().getHostAddress();
 
                           // 5. 获取接收的数据的长度.
                           int len = packet.getLength();
                           // 6. 取出数据. 字节-> 字符 解码.
                           String mess = new String(datas, 0, len);
                           System.out.print("发送端:"+ip+"发送了:");
                           System.out.println(mess);
 
                           // 7. 关闭socket.
                           socket.close();
               }
}
 

 

 

循环发送数据,遇到bye结束循环发送数据

发送端:
public class SendTest1 {
          public static void main(String[] args) throws IOException {
                             // 1.控制台获取用户的输入.
                             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                             // 2. 创建Socket
                             DatagramSocket socket = new DatagramSocket();
 
                             while(true){
                                          System.out.println("请输入:");
                                          String mess = br.readLine();
                                          // 3.  字符串转换为字节数组.
                                          byte[] buffer = mess.getBytes();
                                          // 4. 创建数据报包对象,封装数据.
                                          DatagramPacket packet = new DatagramPacket(buffer, buffer.length,
                                          InetAddress.getByName("192.168.15.255"), 5000);//广播发送数据
                                          // 5. 发送数据报包.
                                          socket.send(packet);
 
                                          if("bye".equals(mess)){
                                                    break; 
                                         }
                                  }
                                  // 6.关闭socket.
                    socket.close();
                    }
}

 

接收端:
public class ReceiveTest1 {
                   public static void main(String[] args) throws IOException {
                                  // 1. 创建Socket(套接词) .
                                  DatagramSocket socket = new DatagramSocket(5000);
                                  // 2. 创建packet(接收数据报包)
                                  DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
                                  while (true) {
                                                  // 3.使用专业的方法接收数据报包
                                                  socket.receive(packet);
                                                  // 获取的是发送端的ip地址.
                                                  String ip = packet.getAddress().getHostAddress(); 
                                                   System.out.println(ip + "进来了...");
                                                   // 4. 获取数据(获取到了存储数据的缓冲区).
                                                   byte[] datas = packet.getData();
                                                   // 5 获取数据的长度.
                                                   int len = packet.getLength();
                                                   // 6. 解码.
                                                   String mess = new String(datas, 0, len);
                                                   System.out.println(mess);
                                                   if ("bye".equals(mess)) {
                                                                          System.out.println(ip + "离开了...");
                                                                          //break;
                                                      }
                          }
                          //socket.close();
               }
}
 

文件上传程序案例

客户端:
public class Client {
                   public static void main(String[] args) throws IOException {
                                // 1. 控制台获取用户上传的文件的路径.
                                File file = getFile();
                                System.out.println(file);
                                // 2. 创建客户端Socket.
                                Socket socket = new Socket("192.168.15.10", 5000);
                                // 3. 获取客户端socket 的输入和输出流.
                                InputStream in = socket.getInputStream();
                                OutputStream out = socket.getOutputStream();
                                // 4. 将客户端文件的名字上传到服务器.
                                out.write(file.getName().getBytes());
                                // 5. 读取服务端的返回的消息.
                                byte[] buffer = new byte[1024];
                                int len;
                                len = in.read(buffer);
                                String mess = new String(buffer, 0, len);
                                // 6. 根据服务端的响应,判断文件是否存在.
                                if ("文件存在无需上传".equals(mess)) {
                                             System.out.println(mess + ",客户端程序结束!!!");
                                             socket.close();
                                             return;
                                 } else {
                                             System.out.println(mess);
                                 }
                                             System.out.println("客户端开始上传!!!");
                                             // 7. 在客户端创建字节输入流. 读取客户端的文件.
                                             FileInputStream fis = new FileInputStream(file);
                                             // 8. 客户端字节输入流循环读取.
                                             while ((len = fis.read(buffer)) != -1) {
                                                                  // 8. 客户端socket 的输出流写出数据.
                                                                  out.write(buffer, 0, len);
                                              }
                                              // 9. 文件上传完毕,发送结束标记.
                                              socket.shutdownOutput();
                                              // 10. 客户端接收服务器的返回的消息.
                                              len = in.read(buffer);
                                              System.out.println(new String(buffer, 0, len));
                                              // 11. 关闭客户端socket 客户端字节输入流.
                                              fis.close();
                                              socket.close();
                           }
 }
public static File getFile() throws IOException {
                         // 1.控制台获取用户需要上传的文件的路径.
                         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                         while (true) {
                                        System.out.println("请输入上传文件的路径:");
                                        String filePath = br.readLine();
                                        File file = new File(filePath);
                                        // 2.路径不存在.
                                        if (!file.exists()) {
                                                  System.out.println("路径不存在,请重新输入. ");
                                                  continue;
                                         }
                                        // 2. 不支持目录.
                                        if (file.isDirectory()) {
                                                   System.out.println("暂不支持目录上传,等待升级版!!!");
                                                   continue;
                                         }
                                         return file;
                      }
          }
}

 

服务端
public class Server {
                    public static void main(String[] args) throws IOException {
                                // 1. 创建服务端.
                                System.out.println("tcp 服务器启动.准备接收文件");
                                ServerSocket server = new ServerSocket(5000);
                                while (true) {
                                               // 2. accept 方法等待客户端连接.
                                               final Socket socket = server.accept();
                                               new Thread(new Runnable() {
                                               @Override      //复写run()            => 创建多线程
                                               public void run() {
                                                            String ip = socket.getInetAddress().getHostAddress();
                                                            System.out.println("客户端:" + ip + "连接了..");
                                                            try {
                                                                     // 3. 获取服务端socket 的输入和输出流.
                                                                     InputStream in = socket.getInputStream();
                                                                     OutputStream out = socket.getOutputStream();
                                                                     byte[] buffer = new byte[1024 * 8];
                                                                     int len;
                                                                     // 4. 服务接收文件的名字.
                                                                     len = in.read(buffer);
                                                                     String fileName = new String(buffer, 0, len);
                                                                     // 5. 在服务器明确该文件保存的路径...
                                                                     File dir = new File("e:\\upload");
                                                                     // 检测该目录是否存在. 如果不存在,必须创建.
                                                              if (!dir.exists()) {
                                                                     dir.mkdir();
                                                              }
                                                             // 6. 根据客户端上传的文件名,封装为一个File 对象.
                                                             File file = new File(dir, fileName);
                                                             // 7. 服务器, 检测文件是否存在. 如果存在就不再重复上传.
                                                         if (file.exists()) {
                                                             out.write("文件存在无需上传".getBytes());
                                                             socket.close();
                                                             return;
                                                         } else {
                                                                  out.write("文件不存在可以上传".getBytes());
                                                         }
                                                         System.out.println("服务端开始接收");
                                                         // 8. 服务器创建本地的字节输出流. 将socket 读取的数据持   久化存储到服务器.
                                                         FileOutputStream fos = new FileOutputStream(file);
                                                         // 9. 服务器开始接收.
                                                         while ((len = in.read(buffer)) != -1) {
                                                             fos.write(buffer, 0, len);
                                                         }
                                                         System.out.println("服务器接收完毕!!!");
                                                         // 10. 服务器接收完毕,想客户端发送结束的消息.
                                                         out.write("服务器成功接收完毕".getBytes());
                                                         // 11. 关闭服务端的创建的字节输出流.
                                                         fos.close();
                                                         } catch (IOException e) {
                                                                  // e.printStackTrace();
                                                         } finally {
                                                              try {
                                                                        socket.close();
                                                                  } catch (IOException e) {
                                                                        // e.printStackTrace();
                                                                  }
                                                              System.out.println("客户端:" + ip + "离开了..");
                                                        }
                                             }
                                      }).start();
                          }
             }
}

 

 

  • 大小: 31.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics