zoukankan      html  css  js  c++  java
  • 网络编程

    URL对象

    • URL类

      1. URL(Uniform Resource Locator)

        一致资源定位器的简称,表示Internet上某一资源的地址

      2. URL的组成

        protocol:resourceNamae

        协议名指明获取资源所使用的的传输协议,如http、ftp等,资源名则是资源的完整地址,包括主机名、端口号或文件内部的一个引用。

      3. 获取URL对象属性

        Public String getProtocol()
        
        Public String getHost()
        
        public String getPort()
        
        public String getFile()
        

    URLConnection对象

    • 一个URLConnection对象代表一个URL资源与Java程序的通讯连接,可以通过它对这个URL资源读或写。

    • 与URL的区别

      1. URL是单向的,URLConnection是双向的

      2. 可以查看服务器的响应消息的首部

      3. 可以设置客户端请求消息的首部

    • 使用示例

      关键步骤:构造一个URL对象,调用URL对象的openConnection()方法获取对应该URL的URLConnection对象。

      public class URLConnector {
          public static void main(String[] args) {
              try {
                  URL cs = new URL("http://www.sina.com/");
                  URLConnection tc = cs.openConnection();
                  BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
                  String inputLine;
                  while((inputLine = in.readLine()) != null) {
                      System.out.println(inputLine);
                  }
                  in.close();
              } catch (MalformedURLException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      

    Get与Post请求

    • 示例

      public static String sendGet(String url, String param) {
          String result = "";
          BufferedReader in = null;
          try {
              String urlNameString = url + "?" +param;
              URL realUrl = new URL(urlNameString);
              URLConnection connection = realUrl.openConnection();
              connection.setRequestProperty("accept", "*/*");
              connection.setRequestProperty("connection", "Keep-Alive");
              connection.connect();
              in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
              String line;
              while((line=in.readLine()) != null) {
                  result += line;
              }
          } catch (MalformedURLException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              try {
                  if (in != null) {
                      in.close();
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return result;
          }
      }
      
      public static String sendPost(String url, String param) {
          PrintWriter out = null;
          BufferedReader in = null;
          String result = "";
          try {
              URL realUrl = new URL(url);
              URLConnection connection = realUrl.openConnection();
              connection.setRequestProperty("accept", "*/*");
              connection.setRequestProperty("connection", "Keep-Alive");
              connection.setDoOutput(true);
              out = new PrintWriter(connection.getOutputStream());
              out.print(param);
              out.flush();
              in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
              String line;
              while((line=in.readLine()) != null) {
                  result += line;
              }
          } catch (MalformedURLException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              try {
                  if (in != null) {
                      in.close();
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return result;
          }
      }
      
    • HttpURLConnection类

      在URLConnection的基础上提供一系列针对http请求的内容

      1. HTTP状态码(例如HTTP_OK:200)
      2. setRequestMethod(设置请求方法GETPOST等)
      3. getResponseCode(获取HTTP的响应)

    Socket通信原理

    • TCP传输协议(Transport Control Protocol)

      面向连接的能够提供可靠的流式数据传输的协议

      URL,URLConnection,Sokcet,ServerSocket等类都使用TCP协议进行网络通讯。

    • socket通讯

      网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个socket。

    Socket通信实现

    • 创建socket

      使用Socket类构造

    • 客户端socket的建立

    • 服务端socket的建立

    • 打开输入输出流

    • 关闭socket

      注意先关闭流再关闭socket

      @TalkClient.java

      import java.net.*;
      import java.io.*;
      
      public class TalkClient {
          public static void main(String[] args) {
              System.out.println("Client Start...");
              try {
                  Socket socket = new Socket("127.0.0.1", 8888);
                  BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
                  PrintWriter os = new PrintWriter(socket.getOutputStream());
                  BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                  String readline;
                  readline = sin.readLine();
                  while (!readline.equals("bye")) {
                      os.println(readline);
                      os.flush();
                      System.out.println("Client:" + readline);
                      System.out.println("Server:" + is.readLine());
                      readline = sin.readLine();
                  }
                  os.close();
                  is.close();
                  socket.close();
              } catch (UnknownHostException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      

      @TalkServer.java

      public class TalkServer {
          public static void main (String[] args) {
              System.out.println("Server start...");
              try {
                  ServerSocket server = new ServerSocket(8888);
                  Socket socket = server.accept();
                  String readline;
                  BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                  PrintWriter os = new PrintWriter(socket.getOutputStream());
                  BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
                  System.out.println("Client: "+is.readLine());
                  readline = sin.readLine();
                  while (!readline.equals("bye")) {
                      os.println(readline);
                      os.flush();
                      System.out.println("Server:" + readline);
                      System.out.println("Client:" + is.readLine());
                      readline = sin.readLine();
                  }
                  os.close();
                  is.close();
                  socket.close();
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      

      注意os.print()与os.println()的区别,不要被回车符坑了!!!

    Socket多客户端通信

    @MultiTalkClient.java

    public class MultiTalkClient {
        int num;
        public static void main(String[] args) {
            System.out.println("Client Start...");
            try {
                Socket socket = new Socket("127.0.0.1", 8888);
    
                BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
                PrintWriter os = new PrintWriter(socket.getOutputStream());
                BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    
                String readline;
                readline = sin.readLine();
                while (!readline.equals("bye")) {
                    os.println(readline);
                    os.flush();
                    System.out.println("Client:" + readline);
                    System.out.println("Server:" + is.readLine());
                    readline = sin.readLine();
                }
                os.close();
                is.close();
                socket.close();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    @ServerThread.java

    public class ServerThread extends Thread {
        Socket socket = null;
        int clientNum;
    
        public ServerThread(Socket socket, int num) {
            this.socket = socket;
            this.clientNum = num + 1;
        }
    
        @Override
        public void run() {
            try {
                String line;
    
                BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
                PrintWriter os = new PrintWriter(socket.getOutputStream());
                BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    
                System.out.println("Client"+clientNum+":"+is.readLine());
                line = sin.readLine();
                while (!line.equals("bye")) {
                    os.println(line);
                    os.flush();
                    System.out.println("Server:" + line);
                    System.out.println("Client"+clientNum+":"+is.readLine());
                    line = sin.readLine();
                }
                os.close();
                is.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    @MultiTalkServer.java

    public class MultiTalkServer {
        static int clientNum = 0;
        public static void main (String[] args) {
            System.out.println("Server start...");
            try {
                ServerSocket serverSocket = null;
                Boolean listening = true;
                try {
                    serverSocket = new ServerSocket(8888);
                } catch (IOException e) {
                    System.out.println("Could not listen on port:8888");
                    System.exit(-1);
                }
                while (listening) {
                    new ServerThread(serverSocket.accept(), clientNum).start();
                    clientNum++;
                }
                serverSocket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    数据报通信

    • UDP(User Datagram Protocol)

      非面向连接的提供不可靠的数据包式的数据传输协议。

      DatagramPacket,DatagramSocket,MulticastSocket等类使用UDP协议进行网络通讯。

    • TCP(Transport Control Protocol)

      面向连接的能够提供可靠的流式数据传输的协议。

      URL,URLConnection,Socket,ServerSocket等类都使用TCP协议进行网络通讯。

    • 区别

      1. TCP有建立时间

      2. UDP传输有大小限制:64k以内

      3. TCP的应用:Telnet,ftp

      4. UDP的应用:ping

    • 使用数据报通信

      DatagramSocket()

      DatagramPacket()

    • 收数据报

      DatagramPacket packet = new DatagramPacket(buf,256);
      socket.recive(packet);
      
    • 发数据报

      DatagramPacket packet = new DatagramPacket(buf,buf.length,address,port);
      socket.send(packet);
      
    • 示例

      @QuoteClient.java

      public class QuoteClient {
          public static void main(String[] args) throws IOException {
              if (args.length != 1) {
                  System.out.println("Usage:java QuoteClient <hostname>");
                  return;
              }
      
              DatagramSocket socket = new DatagramSocket();
      
              //send request
              byte[] buf = new byte[256];
              InetAddress address = InetAddress.getByName(args[0]);
              DatagramPacket packet = new DatagramPacket(buf,buf.length,address,8888);
              socket.send(packet);
      
              //get response
              packet = new DatagramPacket(buf,buf.length);
              socket.receive(packet);
      
              //display response
              String received = new String(packet.getData());
              System.out.println("Quote of the Moment:"+received);
      
              socket.close();
          }
      }
      

      @QuoteServerThread.java

      public class QuoteServerThread extends Thread {
          protected DatagramSocket socket = null;
          protected BufferedReader in = null;
          protected boolean moreQuotes = true;
      
          public QuoteServerThread() throws SocketException {
              this("QuoteServerThread");
          }
      
          public QuoteServerThread(String name) throws SocketException {
              super(name);
              socket = new DatagramSocket(8888);
              try {
                  in = new BufferedReader(new FileReader("one-liners.txt"));
              } catch (FileNotFoundException e) {
                  System.err.println("Could not open quote file. Serving time instead.");
              }
          }
      
          @Override
          public void run() {
              while(moreQuotes) {
                  try {
                      byte[] buf = new byte[256];
                      DatagramPacket packet = new DatagramPacket(buf,buf.length);
                      socket.receive(packet);
                      String dString = null;
                      if (in == null)
                          dString = new Date().toString();
                      else
                          dString = getNextQuote();
                      buf = dString.getBytes();
      
                      //send response
                      InetAddress address = packet.getAddress();
                      int port = packet.getPort();
                      packet = new DatagramPacket(buf,buf.length,address,port);
                      socket.send(packet);
                  } catch (IOException e) {
                      e.printStackTrace();
                      moreQuotes = false;
                  }
              }
              socket.close();
          }
      
          protected String getNextQuote() {
              String res = null;
              try {
                  if ((res = in.readLine()) == null) {
                      in.close();
                      moreQuotes = false;
                      res = "No more quotes.";
                  }
              } catch (IOException e) {
                  res = "IOException occured in server";
              }
      
              return res;
          }
      }
      

      @QuoteServer.java

      public class QuoteServer {
          public static void main(String[] args) throws IOException {
              new QuoteServerThread().start();
          }
      }
      

    使用数据报进行广播通信

    DatagramSocket只允许数据报发往一个目的地址

    MulticastSocket将数据报以广播方式发送到该端口的所有客户

    MulticastSocket用在客户端,监听服务器广播来的数据

    • 示例

      @MulticastClient.java

      public class MulticastClient {
          public static void main(String[] args) throws IOException {
              MulticastSocket socket = new MulticastSocket(4396);
              InetAddress address = InetAddress.getByName("230.0.0.1");
              socket.joinGroup(address);
              DatagramPacket packet;
      
              //get a few quotes
              for(int i=0;i<5;i++) {
                  byte[] buf = new byte[256];
                  packet = new DatagramPacket(buf,buf.length);
                  socket.receive(packet);
                  String received = new String(packet.getData());
                  System.out.println("Quote of the Moment:"+received);
              }
              socket.leaveGroup(address);
              socket.close();
          }
      }
      

      @MulticastServerThread.java

      public class MulticastServerThread extends QuoteServerThread{
          private long FIVE_SECOND = 5000;
          public MulticastServerThread() throws IOException {
              super("MulticastServerThread");
          }
      
          @Override
          public void run() {
              while (moreQuotes) {
                  try {
                      byte[] buf = new byte[256];
                      String dString = null;
                      if (in == null)
                          dString = new Date().toString();
                      else
                          dString = getNextQuote();
                      buf = dString.getBytes();
      
                      //send it
                      InetAddress group = InetAddress.getByName("230.0.0.1");
                      DatagramPacket packet = new DatagramPacket(buf,buf.length,group,4396);
                      socket.send(packet);
      
                      //sleep for a while
                      try {
                          sleep((long)(Math.random()*FIVE_SECOND));
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  } catch (IOException e) {
                      e.printStackTrace();
                      moreQuotes = false;
                  }
              }
              socket.close();
          }
      }
      

      @MulticastServer.java

      public class MulticastServer {
          public static void main(String[] args) throws IOException {
              new MulticastServerThread().start();
          }
      }
      

    网络聊天程序

    @ChatFrame.java

    public class ChatFrame extends JFrame implements ActionListener {
        JTextField tf;
        JTextArea ta;
        JScrollPane sp;
        JButton send;
        JPanel p;
    
        int port;
        String s = "";
        String myID;
        Date date;
        ServerSocket server;
        Socket mySocket;
        BufferedReader is;
        PrintWriter os;
        String line;
    
        public ChatFrame(String ID,String remoteID,String IP,int port, boolean isServer) {
            super(ID);
            myID = ID;
            this.port = port;
            ta = new JTextArea();
            ta.setEditable(false);
            sp = new JScrollPane(ta);
            this.setSize(330,400);
            this.setResizable(false);
    
            try{
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            this.getContentPane().add(sp,"Center");
            p = new JPanel();
            this.getContentPane().add(p,"South");
            send = new JButton("发送");
            tf = new JTextField(20);
            tf.requestFocus();
            p.add(tf);
            p.add(send);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            this.setVisible(true);
            send.addActionListener(this);
            tf.addActionListener(this);
    
            if(isServer) {
                try {
                    server = null;
                    try {
                        server = new ServerSocket(port);
                    }catch (Exception e) {
                        e.printStackTrace();
                    }
                    mySocket = null;
                    try {
                        mySocket = server.accept();
                    }catch (Exception e) {
                        e.printStackTrace();
                    }
                    is = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
                    os = new PrintWriter(mySocket.getOutputStream());
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else {
                try {
                    mySocket = new Socket(IP,port);
                    os = new PrintWriter(mySocket.getOutputStream());
                    is = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            while (true) {
                try {
                    line = is.readLine();
                    date = new Date();
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String currentTime = formatter.format(date);
                    s+=currentTime+" "+remoteID+"说:
    "+line+"
    ";
                    ta.setText(s);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        @Override
        public void actionPerformed(ActionEvent actionEvent) {
            date = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String currentTime = formatter.format(date);
            s+=currentTime+" "+myID+"说:
    "+tf.getText()+"
    ";
            ta.setText(s);
            os.println(tf.getText());
            os.flush();
            tf.setText("");
            tf.requestFocus();
        }
    }
    

    @ChatServerFrame.java

    public class ChatServerFrame {
        public static void main(String[] args) {
            ChatFrame cserver = new ChatFrame("Cat","Dog","localhost",4396,true);
        }
    }
    

    @ChatClientFrame.java

    public class ChatClientFrame {
        public static void main(String[] args) {
            ChatFrame cclient = new ChatFrame("Dog","Cat","localhost",4396,false);
        }
    }
    

    实际运行如下图所示:

  • 相关阅读:
    pointcut通配符
    Java设计模式-建造者(Builder)模式
    mybatis 初步使用(IDEA的Maven项目, 超详细)
    静态代理和动态代理
    Java 多线程(五)之 synchronized 的使用
    Java 多线程(四)之守护线程(Daemon)
    HashMap 源码解析(一)之使用、构造以及计算容量
    Java 多线程(三)之线程状态及其验证
    Java 多线程(二)之 Thread 优先级
    Java 多线程之 Thread 类 和 Runnable 接口初步使用
  • 原文地址:https://www.cnblogs.com/hunter-w/p/13764207.html
Copyright © 2011-2022 走看看