网络编程入门

1.1 概述

计算机网络:地理位置不同 多台计算机 连接 通信 共享

网络编程的目的:数据交换,通信

如何实现多台主机之间的数据通信:

  1. 准确定位网络上的一台主机以及该主机的某个资源(IP:Port)
  2. 传输数据?

JavaWeb:网页编程 B/S

网络编程:TCP/IP C/S

1.2 网络通信的要素

实现网络通信需要知道通信双方地址(ip、端口号)

规则:网络通信协议

TCP/IP参考模型:

img

网络编程专门针对传输层(TCP/IP)

1.3 IP

ip地址:InetAddress

  • 唯一定位一台网络上的计算机
  • 127.0.0.1:本机localhost
  • ip地址的分类:

    • ipv4/ipv6

      • ipv4:10.164.120.176 4个字节组成,0~255,42亿中30亿在北美,亚洲4亿,2011年就用尽
      • ipv6:fe80::a1a2:85b0:e7d9:58f1%7 128位,8个无符号整数
    • 公网(互联网) 私网(局域网)

      • ABCD类地址
      • 192.168.xx.xx 专门给组织内部使用的
  • 域名→记忆IP问题!

1.4 端口

端口表示计算机上的一个程序的进程:

  • 不同进程有不同的端口号!(不能冲突)用来区分进程!
  • 范围:0~65535
  • TCP,UDP:65535*2 单个协议下,端口号不能冲突
  • 端口分类

    • 公有端口 0~1023

      • HTTP:80
      • HTTPS:443
      • FTP:21
      • Telnet:23
    • 程序注册端口:1024~49151 分配给用户或者程序

      • Tomcat:8080
      • MySQL:3306
      • Oracle:1521
    • 动态/私有端口:49152~65535

      netstat -ano #查看所有端口
      netstat -ano|findstr "端口号" #查看指定的端口
      tasklist|findstr "端口号" #查看指定端口的进程

1.5 通信协议

协议:约定

网络通信协议:速率,传输码率,代码结构,传输控制......

TCP/IP协议簇

重要:

  • TCP:传输控制协议
  • UDP:用户数据报协议

TCP vs UDP

打电话~TCP

  • 连接,稳定
  • 三次握手,四次挥手

    最少需要三次,保证稳定连接!
    A:你瞅啥?
    B:瞅你咋地?
    A:干一场!
    
    A:我要走了
    B:你真的要走了吗?
    B:你真的真的要走了吗?
    A:我真的真的要走了!

    img

  • 客户端、服务端
  • 传输完成,释放连接,效率低

发短信~UDP

  • 不连接,不稳定
  • 客户端、服务器:没有明确的界限
  • 不管有没有准备好,都可以发给你
  • 导弹
  • DDoS:洪水攻击(饱和攻击)

1.6 TCP

聊天

客户端

  1. 通过Socket连接服务器
  2. 发送消息
package tcp;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        InetAddress serverIP = null;
        int port = 0;
        Socket socket = null;
        OutputStream os = null;
        try {
            //1.得知服务器地址
            serverIP = InetAddress.getByName("127.0.0.1");
            port = 9999;
            //2.创建一个socket连接
            socket = new Socket(serverIP,port);
            //3.发送消息
            os = socket.getOutputStream();
            os.write("你好".getBytes());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(socket!=null){
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }        
    }
}

服务器端

  1. 建立服务端口
  2. 通过accept等待用户连接
  3. 接收用户消息
package tcp;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        
        try {
            //1.有地址
            serverSocket = new ServerSocket(9999);
            //2.等待客户端连接
            socket = serverSocket.accept();
            //3.读取客户端的消息
            is = socket.getInputStream();
            //管道流
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while((len=is.read(buffer))!=-1){
                baos.write(buffer,0,len);
            }
            System.out.println(baos.toString());
            
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            //关闭资源
            if(baos!=null){
                try {
                    baos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(serverSocket!=null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

文件上传

服务器端

package tcp;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.omg.CORBA_2_3.portable.OutputStream;

public class Server {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub    
        try {
            //1.创建服务
            ServerSocket serverSocket = new ServerSocket(9999);
            //2.监听客户端连接
            Socket socket = serverSocket.accept();
            //3.读取输入流
            InputStream is = socket.getInputStream();
            //4.文件输出
            FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
            byte[] buffer = new byte[1024];
            int len;
            while((len=is.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }
            //5.关闭资源
            is.close();
            fos.close();
            socket.close();
            serverSocket.close();                    
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

客户端

package tcp;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        try {
            //1.创建一个socket连接
            Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9999);
            //2.创建一个输出流
            OutputStream os = socket.getOutputStream();
            //3.读取文件
            FileInputStream fis = new FileInputStream(new File("dog.jpg"));
            //4.写出文件
            byte[] buffer = new byte[1024];
            int len;
            while((len=fis.read(buffer))!=-1){
                os.write(buffer,0,len);
            }
            //5.关闭资源
            fis.close();
            os.close();
            socket.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }        
    }
}

服务端(Tomcat)

客户端(浏览器)

1.7 UDP

发短信:不用连接,需要知道对方地址

发送消息

发送端

package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

//不需要连接服务器
public class Client {
    public static void main(String[] args) throws Exception {
    //1.建立一个Socket
    DatagramSocket socket = new DatagramSocket();
    //2.建个包    
    String msg = "Hello!";
    InetAddress localhost = InetAddress.getByName("localhost");
    int port = 9090;
    //数据,数据的长度起始,发送给谁
    DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
    //3.发送包
    socket.send(packet);
    //4.关闭流
    socket.close();
    }
}

接收端

package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

//还是要等待客户端的连接!
public class Server {
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        //开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        //接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length); //接收
        socket.receive(packet);//阻塞接收
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));
        //关闭连接
        socket.close();
    }
}

循环发送消息

发送端

package udp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class Sender {

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket(8888);
        //准备数据:控制台读取
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while(true){
            //2.建个包    
            String data = reader.readLine();
            byte[] datas = data.getBytes();        
            //数据,数据的长度起始,发送给谁
            DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));
            //3.发送包
            socket.send(packet);
            if(data.equals("bye")){
                break;
            }
        }    
        //4.关闭流
        socket.close();
    }
}

接收端

package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Receiver {

    public static void main(String[] args) throws Exception {
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket(6666);
        
        while(true){
            //准备接收包裹
            byte[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container,0,container.length);
            socket.receive(packet);//阻塞式接收包裹
            //断开连接 bye
            byte[] data = packet.getData();
            String receiveData = new String(data,0,data.length).trim();
            System.out.println(receiveData);
            if(receiveData.equals("bye")){
                break;
            }            
        }        
        //关闭流
        socket.close();
    }
}

在线咨询:两个人既可以是发送端也可以是接收端(多线程)

线程TalkSend

package udp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class TalkSend implements Runnable{
    DatagramSocket socket = null;
    BufferedReader reader = null;
    
    private int fromPort;
    private String toIP;
    private int toPort;
    

    public TalkSend(int fromPort, String toIP, int toPort) {
        super();
        this.fromPort = fromPort;
        this.toIP = toIP;
        this.toPort = toPort;
        try {
            socket = new DatagramSocket(fromPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while(true){
            String data;
            try {
                data = reader.readLine();
                byte[] datas = data.getBytes();        
                DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIP,this.toPort));
                socket.send(packet);
                if(data.equals("bye")){
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }    
        socket.close();
    }
}

线程TalkReceive

package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class TalkReceive implements Runnable{
    DatagramSocket socket = null;
    private int port;
    private String msgFrom;
    
    public TalkReceive(int port,String msgFrom) {
        super();
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            socket = new DatagramSocket(port);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void run() {    
        while(true){
            try {
                //准备接收包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container, 0,container.length);
                socket.receive(packet);//阻塞式接收包裹
                //断开连接 bye
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, data.length).trim();
                System.out.println(msgFrom+":"+receiveData);
                if (receiveData.equals("bye")) {
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }            
        }        
        //关闭流
        socket.close();
    }
}

老师TalkTeacher

package udp;

public class TalkTeacher {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Thread(new TalkSend(5555,"localhost",8888)).start();
        new Thread(new TalkReceive(9999,"学生")).start();    }
}

学生TalkStudent

package udp;

public class TalkStudent {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(7777,"localhost",9999)).start();
        new Thread(new TalkReceive(8888,"老师")).start();
    }
}

1.8 URL

统一资源定位符:定位互联网资源

协议://ip地址:端口/项目名/资源

url下载网络资源

package url;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class URLDown {

    public static void main(String[] args) throws Exception {
        //1.下载地址
        URL url = new URL("http://127.0.0.1:8080/zhg/Confidential.txt");
        //2.连接这个资源HTTP
        HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
        InputStream inputStream = urlConnection.getInputStream();
        FileOutputStream fos = new FileOutputStream("cfile.txt");
        byte[] buffer = new byte[1024];
        int len;
        while((len=inputStream.read(buffer))!=-1){
            fos.write(buffer, 0, len); 
        }
        fos.close();
        inputStream.close();
        urlConnection.disconnect();
    }
}

你可能感兴趣的:(java,java-se,网络编程,tcp,udp)