网络编程

1. 概述

  • 计算机网络:是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统
  • 网络编程的目的:传播交流信息、数据交换、通信
  • IP:端口 定位到这个计算机上的资源
  • javaweb:网页编程 B/S
  • 网络编程: TCP/IP C/S

2. 网络通信的要素

  • IP和端口号

  • 网络通信协议 tcp、udp

网络编程

3. IP

  • ip地址:InetAddress

  • 唯一定位一台网络上的计算机

  • 127.0.0.1 本机localhost

  • ip地址的分类

    • ipv4 / ipv6

      • ipv4:例如:127.0.0.1,由4个字节(32位)组成,每个字节长度0-255,大概42亿个
      • ipv6:例如:2000:0bb2:1245:0000:0000:1aaa:1212:21cc,128位。8个无符号整数
    • 公网(互联网) / 私网(局域网)

      • ABCDE类地址

        • A类IP范围 1.0.0.1 - 126.255.255.254

          B类IP范围 128.1.0.1 - 191.254.255.254

          C类IP范围 192.0.1.1 - 223.255.254.254

          D类IP范围 224.0.0.1 - 239.255.255.254

          E类IP范围 240.0.0.0 - 255.255.255.254

      • 192.168.xxx.xxx,专门给组织内部使用的局域网

    //测试ip
    public class TestInetAddress{
        public static void main(String[] args){
            try{
                //查询本机ip地址
                InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
                System.out.println(inetAddress1);
                InetAddress inetAddress2 = InetAddress.getByName("localhost");
                System.out.println(inetAddress2);
                InetAddress inetAddress3 = InetAddress.getLocalHost();
                System.out.println(inetAddress3);
                
                //查询网站ip地址
                InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
                System.out.println(inetAddress4);
                
                //常用方法
                System.out.println(inetAddress4.getAddress()); // [B@7852e922
                System.out.println(inetAddress4.getCanonicalHostName()); //规范的地址 14.215.177.38
                System.out.println(inetAddress4.getHostAddress()); //ip 14.215.177.38
                System.out.println(inetAddress4.getHostName()); //域名 www.baidu.com
                
            }catch(UnknownHostException e){
                e.printStackTrace();
            }
        }
    }
    

4. 端口

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

  • 不同的进程有不同的端口号,用来区分软件

  • 被规定0-65535

  • TCP,UDP:65535*2

  • 端口分类

    • 公有端口:0-1023
      • HTTP:80
      • HTTPS:443
      • FTP:21
      • Telent:23
    • 程序注册端口:1024-49151,分配用户或者程序
      • Tomcat:8080
      • MySQL:3306
      • Oracle:1521
    • 动态、私有:49152-65535(尽量别占用)
  • dos常用命令

    netstat -ano #查看所有的端口
    netstat -ano|findstr "8080" #查看指定的端口
    tasklist|findstr "8080" #查看指定端口的进程
    
    //测试端口
    public class TestInetSocketAddress {
    	public static void main(String[] args) {
    		InetSocketAddress address = new InetSocketAddress("127.0.0.1",8080);
    		InetSocketAddress address2 = new InetSocketAddress("localhost",8080);
    		
    		System.out.println(address); // /127.0.0.1:8080
    		System.out.println(address2); //localhost/127.0.0.1:8080
    		
            //常用方法
    		System.out.println(address.getAddress()); // /127.0.0.1
    		System.out.println(address.getHostName()); //地址 /127.0.0.1
    		System.out.println(address.getPort()); //端口 8080
    	}
    }
    

5. 通信协议

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

  • TCP/IP协议簇:实际上是一组协议

    • 重要的协议
      • TCP:用户传输协议
      • UDP:用户数据报协议
    • 出名的协议
      • TCP:用户传输协议
      • IP:网络互连协议
  • TCP、UDP对比

    • TCP:打电话

      • 连接、稳定

      • 三次握手 四次挥手:至少连接三次才能保持连接

        #三次握手
        A:你瞅啥?
        B:瞅你咋的?
        A:干一场!
        连接成功......
        
        #四次挥手
        A:我要走了!
        B:你要走了吗?
        B:你真的要走了吗?
        A:我真的要走了!
        已断开......
        
      • 客户端、服务端

      • 传输完成,释放连接,效率低

    • UDP:发短信

      • 不连接,不稳定
      • 客户端、服务端:没有明确的界限
      • 不管有没有准备好,都可以发送出去

6. TCP

服务端:

1.建立服务的端口ServerSocket

2.等待用户的连接accept

3.接收用户信息

//服务端
public class TcpServer {

	public static void main(String[] args) {
		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();
			
			/*
			 byte[] buffer = new byte[1024];
			 int len;
			 while((len = is.read(buffer))!=-1){
			 	String msg = new String(buffer,0,len);
			 	System.out.println(msg);
			 }
			  
			*/
			
			//管道流
			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) {	
			e.printStackTrace();
		}finally {
			//关闭资源
			if(baos != null) {
				try {
					baos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(serverSocket != null) {
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
	}
}

客户端:

1.连接服务器Socket

2.发送消息

//客户端
public class TcpClient {

	public static void main(String[] args) {
		Socket socket = null;
		OutputStream os = null;
		
		try {
			//1.要知道服务器的地址,端口号
			InetAddress serverIP = InetAddress.getByName("127.0.0.1");
			int port = 9999;
			
			//2.创建一个socket连接
			socket = new Socket(serverIP,port);
			
			//3.发送消息 IO流
			os = socket.getOutputStream();
			os.write("你好!".getBytes());
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

}

TCP实现文件上传

//客户端
public class TcpClient {
	public static void main(String[] args) throws Exception{
        //创建一个Socket连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
        //创建一个输出流
        OutputStream os = socket.getOutputStream();
        //读取文件
        FileInputStream fis = new FileInputStream(new File("D:\\1.jpg"));
        //写出文件
        byte[] buffer = new byte[1024];
        int len;
        while((len = fis.read(buffer)) != -1){
            os.write(buffer,0,len);
        }
        //通知服务器传输完毕
        socket.shutdownOutput();
        //确定服务器接收完毕,断开连接
        InputStream is = socket.getInputStream();
        //管道流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while((len2 = is.read(buffer2)) != -1){
            baos.write(buffer2,0,len2);
        }
        System.out.println(baos.toString());
        //关闭资源
        baos.close();
        is.close();
        fis.close();
        os.close();
        socket.close();
    }
}

//服务端
public class TcpServer {
	public static void main(String[] args) throws Exception{
        //创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        //监听客户端的连接
        Socket socket = serverSocket.accept(); //阻塞式监听,会一直等待客户端连接
        //获取输入流
        InputStream is = socket.getInputStream();
        //文件输出
        FileOutputStream fos = new FileOutputStream(new File("D:\\11.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }
        //接收完毕通知客户端
        OutputStream os = socket.getOutputStream();
        os.write("已接收完毕,请断开连接!".getBytes());
        //关闭资源
        os.close();
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

7. UDP

  • 不用连接,需要只要对方的地址

    //发送端
    //不需要连接服务器
    public class UdpClient {
    	public static void main(String[] args) throws Exception {
    		//1.建立一个socket
    		DatagramSocket socket = new DatagramSocket();
    		//2.建包
    		String msg = "你好服务器";
    		//3.发送给谁
    		InetAddress localhost = InetAddress.getByName("localhost");
    		int port = 9090;
    		//4.数据,数据长度起始,要发送给谁
    		DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0 ,msg.getBytes().length, localhost, port);
    		//5.发送包
    		socket.send(packet);
    		//6.关闭流
    		socket.close();
    	}
    }
    
    //接收端
    //等待客户端的连接
    public class UdpServer {
    	public static void main(String[] args) throws Exception{
    		//开放端口
    		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();
    	}
    }
    
  • 循环发送接收消息

    //发送者
    public class UdpSender {
    	public static void main(String[] args) throws Exception {
    		//1.建立一个socket
    		DatagramSocket socket = new DatagramSocket(8888);
    		//2.准备数据
    		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    		while(true) {
    			String data = reader.readLine();
    			byte[] datas = data.getBytes();
    			//3.数据,数据长度起始,要发送给谁
    			DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666));
    			//4.发送包
    			socket.send(packet);
    			if(data.equals("bye")) {
    				break;
    			}
    		}
    		//5.关闭流
    		socket.close();
    	}
    }
    
    //接收者
    public class UdpReceive {
    	public static void main(String[] args) throws Exception {
    		//开放端口
    		DatagramSocket socket = new DatagramSocket(6666);
    		while(true) {
    			//准备接收包裹
    			byte[] container = new byte[1024];
    			DatagramPacket packet = new DatagramPacket(container, 0, container.length);
    			socket.receive(packet); //阻塞式接收
    			//断开连接
    			byte[] data = packet.getData();
    			String receiveData = new String(data,0,data.length);
    			System.out.println(receiveData);
    			if(receiveData.equals("bye")) {
    				break;
    			}
    		}
    		socket.close();
    	}
    }
    
  • 实现聊天

    发送类

    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
    			socket = new DatagramSocket(fromPort);
    			//准备数据
    			reader = new BufferedReader(new InputStreamReader(System.in));
    		} catch (SocketException 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 (IOException e) {
    				e.printStackTrace();
    			}
    		}
    		// 关闭流
    		socket.close();
    	}
    }
    

    接收类

    public class TalkReceive implements Runnable {
    	DatagramSocket socket = null;
    	private int port;
    	private String msgFrom;
    	
    	public TalkReceive(int port,String msgFrom) {
    		this.port = port;
    		this.msgFrom = msgFrom;
    		try {
    			// 开放端口
    			socket = new DatagramSocket(port);
    		} catch (SocketException e) {
    			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);// 阻塞式接收
    				// 断开连接
    				byte[] data = packet.getData();
    				String receiveData = new String(data, 0, data.length);
    				System.out.println(msgFrom+":"+receiveData);
    				if (receiveData.equals("bye")) {
    					break;
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			} 
    		}
    		socket.close();
    	}
    }
    

    老师

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

    学生

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

运行截图

8. URL

  • 统一资源定位符:定位互联网上的某一个资源

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

    public class Url {
    	public static void main(String[] args) throws MalformedURLException {
    		URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=aaa&password=123");
    		System.out.println(url.getProtocol()); //协议
    		System.out.println(url.getHost()); //主机ip
    		System.out.println(url.getPort()); //端口
    		System.out.println(url.getPath()); //文件
    		System.out.println(url.getFile()); //全路径
    		System.out.println(url.getQuery()); //参数
    	}
    }
    
  • URL下载网络资源

    public class UrlDown {
    	public static void main(String[] args) throws Exception {
    	//下载地址
    	URL url = new URL("http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png");
    	//连接到这个资源
    	HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    	
    	InputStream is = urlConnection.getInputStream();
    	
    	FileOutputStream fos = new FileOutputStream("D:\\baidu.jpg");
    	
    	byte[] buffer = new byte[1024];
    	int len;
    	while((len = is.read(buffer)) != -1) {
    		fos.write(buffer,0,len); //写出数据
    	}
    	fos.close();
    	is.close();
    	urlConnection.disconnect(); //断开连接
    	}
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Remote_Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值