网络编程一(随笔)

一、常用类操作

(一)ip地址

定义:
用来标识网络中一个通信实体的地址。通信实体可以是计算机、路由器等。


IP地址分类:

  • IPV4:32位地址,以点分十进制表示,如:192.168.0.2
  • IPV6:128位,写成8个16位的无符号整数,每个整数用4个16进制表示,数之间用冒号隔开,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984

特殊IP:
127.0.0.1是本机地址
192.168.0.0–192.168.255.255私有地址,属于非注册地址,专门为组织机构内部使用。


方法InetAddress:

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * InetAddress: 多个静态方法
 * 1、getLocalHost:本机
 * 2、getByName:根据域名DNS |  IP地址 -->IP
 * 
 * 两个成员方法
 * 1、getHostAddress: 返回地址
 * 2、getHostName:返回计算机名
 */
public class IPTest {

	public static void main(String[] args) throws UnknownHostException {
		//使用getLocalHost方法创建InetAddress对象  本机
		InetAddress addr = InetAddress.getLocalHost();
		System.out.println(addr.getHostAddress());  //返回:192.168.1.110
		System.out.println(addr.getHostName());  //输出计算机名
		
		//根据域名得到InetAddress对象
		addr = InetAddress.getByName("www.shsxt.com"); 
		System.out.println(addr.getHostAddress());  //返回 shsxt服务器的ip:
		System.out.println(addr.getHostName());  //输出:www.shsxt.com
		
		//根据ip得到InetAddress对象
		addr = InetAddress.getByName("123.56.138.176"); 
		System.out.println(addr.getHostAddress());  //返回 shsxt的ip:123.56.138.176
		System.out.println(addr.getHostName());  //输出ip而不是域名。如果这个IP地 址不存在或DNS服务器不允许进行IP地址和域名的映射,				
	}
}

(二)端口

定义:
IP地址是用来标识一台计算机,但一台计算机上可能提供多个网络应用程序,如何来区分这些不同的程序呢?这就要用到端口。
端口是虚拟的,通过端口,一个主机上可以运行多个网络应用程序。
端口表示是16位的2进制,2个字节,0-65535,UDP、TCP两种协议,同一协议端口不能冲突


每个网络应用程序都有自己的端口

  • 公认端口:0-1023 如:80端口分配给http协议,21端口分配给FTP
  • 注册端口:1024-49151分配用用户进程或应用程序
  • 动态/私有端口:49152-65535

  • 查看所有端口号:netstat -ano
  • 查看指定端口号:netstat -ano|findstr “808”
  • 查看指定进程:tasklist|findstr “808”
  • 查看具体程序:使用任务管理器查看PID

方法InetSocketAddress

import java.net.InetSocketAddress;
/**
 * InetSocketAddress 
 * 1、构造器
 *   new InetSocketAddress(地址|域名,端口);
 * 2、方法
 *  getAddress​()  
 *  getPort()
 *  getHostName()
 */
public class PortTest {

	public static void main(String[] args) {
		//包含端口
		InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",8080);
		InetSocketAddress socketAddress2 = new InetSocketAddress("localhost",9000);
		System.out.println(socketAddress.getHostName());
		System.out.println(socketAddress.getAddress());
		System.out.println(socketAddress2.getAddress());
		System.out.println(socketAddress2.getPort());
	}
}

(三)URL

定义:
同一资源定位符,由四部分组成:协议、存放资源的主机名、端口号、资源文件名。
方法URL

import java.net.MalformedURLException;
import java.net.URL;

/**
 * URL: 统一资源定位器,互联网三大基石之一(html http),区分资源
 * 1、协议
 * 2、域名、计算机
 * 3、端口: 默认80
 * 4、请求资源
 *  http://www.baidu.com:80/index.html?uname=shsxt&age=18#a
 */
public class URLTest01 {

	public static void main(String[] args) throws MalformedURLException {
		URL url = new URL("http://www.baidu.com:80/index.html?uname=shsxt&age=18#a");
		//获取四个值
		System.out.println("协议:"+url.getProtocol());
		System.out.println("域名|ip:"+url.getHost());
		System.out.println("端口:"+url.getPort());
		System.out.println("请求资源1:"+url.getFile());
		System.out.println("请求资源2:"+url.getPath());
		//参数
		System.out.println("参数:"+url.getQuery());
		//锚点
		System.out.println("锚点:"+url.getRef());
	}
}

模拟网络爬虫
案例1:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
public class SpiderTest01 {
	public static void main(String[] args) throws Exception {
		//获取URL
		URL url =new URL("https://www.jd.com");
		//下载资源
		InputStream is = url.openStream();
		BufferedReader br =new BufferedReader(new InputStreamReader(is,"UTF-8"));
		String msg =null;
		while(null!=(msg=br.readLine())) {
			System.out.println(msg);
		}
		br.close();
		//分析
		//处理。。。。
	}
}

案例2:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 网络爬虫的原理 +模拟浏览器
 */
public class SpiderTest02 {
	public static void main(String[] args) throws Exception {
		//获取URL
		URL url =new URL("https://www.dianping.com");
		//下载资源
		HttpURLConnection  conn =(HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
		BufferedReader br =new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
		String msg =null; 
		while(null!=(msg=br.readLine())) {
			System.out.println(msg);
		}
		br.close();
		//分析
		//处理。。。。
	}
}

二、TCP编程

补充套接字
我们开发的网络应用程序位于应用层,TCP和UDP属于传输层协议,在应用层如何使用传输层的服务呢?在应用层和传输层之间则是使用套接字来进行分离,它就像传输层为应用层开的一个小口

TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。
特点:

  • 面向连接
  • 点到点的通信
  • 高可靠性
  • 占用系统资源多,效率低

  • TCP协议基于请求——响应模式
  • 在网络通讯中,第一次主动发起通讯的程序被称作客户端程序
  • 在一次通讯中等待连接的程序被称作服务器端程序
  • 利用IO流实现数据传输
    在这里插入图片描述
    详细步骤:
    在这里插入图片描述
    案例1
    服务器
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * 熟悉流程
 * 创建服务器
 * 1.指定端口:使用ServerSocket创建服务器
 * 2.阻塞式等待连接accept
 * 3.操作:输入输出操作
 * 4.释放资源
 */
public class Server {
    public static void main(String[] args) throws IOException {
        //1.指定端口:使用ServerSocket创建服务器
        ServerSocket server=new ServerSocket(8888);
        // 2.阻塞式等待连接accept
        Socket client=server.accept();
        System.out.println("一个客户端建立了连接!");
        // 3.操作:输入输出操作
        DataInputStream dis=new DataInputStream(client.getInputStream());
        String data=dis.readUTF();
        System.out.println(data);
        // 4.释放资源
        dis.close();
        client.close();
    }
}

服务器

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

/**
 * 熟悉流程
 * 创建客户端
 * 1.建立连接:使用Socket创建客户端+服务的地址和端口
 * 2.操作:输入输出操作
 * 3.释放资源
 */
public class Client {
    public static void main(String[] args) throws IOException {
        //1.建立连接:使用Socket创建客户端+服务的地址和端口
        Socket client=new Socket("localhost",8888);
        //2.操作:输入输出操作
        DataOutputStream dos=new DataOutputStream(client.getOutputStream());
        String data="hello";
        dos.writeUTF(data);
        dos.flush();
        //3.释放资源
        dos.close();
        client.close();
    }
}

案例2:服务器接收多个客户端的请求,并给出反馈
服务器

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 模拟登录 多个客户端请求
 * 创建服务器
 * 1、指定端口 使用ServerSocket创建服务器
 * 2、阻塞式等待连接 accept
 * 3、操作: 输入输出流操作
 * 4、释放资源 
 */
public class LoginMultiServer {
	public static void main(String[] args) throws IOException {
		System.out.println("-----Server-----");
		// 1、指定端口 使用ServerSocket创建服务器
		ServerSocket server =new ServerSocket(8888);
		boolean isRunning =true;;
		// 2、阻塞式等待连接 accept
		while(isRunning) {
			Socket  client =server.accept(); 
			System.out.println("一个客户端建立了连接");
			new Thread(new Channel(client)).start();
		}
		server.close();
	}
	//一个channel就代表一个客户端
	static class Channel implements Runnable{
		private Socket  client;
		//输入流
		private DataInputStream dis;
		//输出流
		private DataOutputStream dos;
		public Channel(Socket  client) {
			this.client = client;
			try {
				//输入
				dis = new DataInputStream(client.getInputStream());
				//输出
				dos =new DataOutputStream(client.getOutputStream());	
			} catch (IOException e) {
				e.printStackTrace();
				release();
			}	
		}	
		//接收数据
		private String receive() {
			String datas ="";
			try {
				datas = dis.readUTF();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return datas;
		}
		//释放资源
		private void release() {
			// 4、释放资源 
			try {
				if(null != dos) {
					dos.close();					
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(null != dis) {
					dis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(null != client) {
					client.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		//发送数据
		private void send(String msg) {
			try {
				dos.writeUTF(msg);
				dos.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		@Override
		public void run() {						
			// 3、操作: 输入输出流操作					
			String uname ="";
			String upwd ="";
			//分析
			String[] dataArray = receive().split("&");
			for(String info:dataArray) {
					String[] userInfo =info.split("=");
					if(userInfo[0].equals("uname")) {
						System.out.println("你的用户名为:"+userInfo[1]);
						uname = userInfo[1];
					}else if(userInfo[0].equals("upwd")) {
						System.out.println("你的密码为:"+userInfo[1]);
						upwd = userInfo[1];
					}				
			}					
			if(uname.equals("shsxt") && upwd.equals("laopei")) { //成功
				send("登录成功,欢迎回来");
			}else { //失败
				send("用户名或密码错误");
			}
			release();
		}
	}
}

客户端

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * 模拟登录  多个客户端请求
 * 创建客户端
 * 1、建立连接: 使用Socket创建客户端 +服务的地址和端口
 * 2、操作: 输入输出流操作
 * 3、释放资源 
 */
public class LoginMultiClient {
	public static void main(String[] args) throws UnknownHostException, IOException {		
		System.out.println("-----Client-----");
		//1、建立连接: 使用Socket创建客户端 +服务的地址和端口
		Socket client =new Socket("localhost",8888);
		//2、操作: 输入输出流操作  先请求后响应
		new Send(client).send();
		new Receive(client).receive();		
		client.close();
	}
	//发送
	static class Send{
		private Socket client;
		private DataOutputStream dos;
		private BufferedReader console ;
		private String msg;
		public Send(Socket client) {			
			console=new BufferedReader(new InputStreamReader(System.in));
			this.msg =init();
			this.client = client;
			try {
				dos=new DataOutputStream(client.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		private String init() {					
			try {
				System.out.print("请输入用户名:");
				String uname =console.readLine();
				System.out.print("请输入密码:");
				String upwd =console.readLine();
				return "uname="+uname+"&"+"upwd="+upwd;
			} catch (IOException e) {
				e.printStackTrace();
			}
			return "";			
		}
		public void send() {
			try {
				dos.writeUTF(msg);
				dos.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	//接收
	static class Receive{
		private Socket client;
		private DataInputStream dis;
		public Receive(Socket client) {
			this.client = client;
			try {
				dis=new DataInputStream(client.getInputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}		
		public void receive() {
			String result;
			try {
				result = dis.readUTF();
				System.out.println(result);
			} catch (IOException e) {
				e.printStackTrace();
			}				
		}
	}
}

三、UDP编程

UDP是一种无连接的传输层协议,提供面向事务的简单不可靠信息传输服务。
特点:

  • 非面向连接,传输不可靠,可能丢失
  • 发送方不管对方是否准备好,接收方收到也不确认
  • 可以广播发送
  • 非常简单的协议,开销小
    案例1:简单的发送接收
    发送端
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
/**
 * 发送端
 * 1.使用DatagramSocket 指定端口 创建发送端
 * 2.准备数据 一定转成字节数组
 * 3.封装成DatagramPacket 包裹,需要指定目的地
 * 4.发送包裹send(DatagramPacket p)
 * 5.释放资源
 */
public class UdpClient {
    public static void main(String[] args) throws Exception {
        System.out.println("发送方启动中......");
        //1.使用DatagramSocket 指定端口 创建发送端
        DatagramSocket client=new DatagramSocket(8888);
        //2.准备数据 一定转成字节数组
        String data="你今天真好看";
        byte[] datas=data.getBytes();
        //3.封装成DatagramPacket 包裹,需要指定目的地
        DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
                new InetSocketAddress("localhost",9999));
        //4.发送包裹send(DatagramPacket p)
        client.send(packet);
        //5.释放资源
        client.close();
    }
}

接收端

import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
 * 接收端
 * 1.使用DatagramSocket 指定端口 创建接收端
 * 2.准备容器 封装成DatagramPacket 包裹
 * 3.阻塞式接收包裹receive(DatagramPacket p)
 * 4.分析数据
 * byte[] getData()
 *        getLength()
 * 5.释放资源
 */
public class UdpServer {
    public static void main(String[] args) throws Exception {
        System.out.println("接收方启动中......");
        //1.使用DatagramSocket 指定端口 创建接收端
        DatagramSocket server=new DatagramSocket(9999);
        //2.准备容器 封装成DatagramPacket 包裹
        byte[] container=new byte[1024*60];
        DatagramPacket packet=new DatagramPacket(container,0,container.length);
        //3.阻塞式接收包裹receive(DatagramPacket p)
        server.receive(packet);
        //4.分析数据
        // byte[] getData()
        //        getLength()
        byte[] datas=packet.getData();
        int len=packet.getLength();
        //5.释放资源
        System.out.println(new String(datas,0,len));
        server.close();
    }
}

案例2:学生和咨询师在线一对一交流
使用面向对象封装:发送端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class TalkSend implements Runnable {
    private DatagramSocket client;
    private BufferedReader reader;
    private String toIP;
    private int toPort;
    public TalkSend(int port,String toIP,int toPort){
        this.toIP=toIP;
        this.toPort=toPort;
        try {
            client=new DatagramSocket(port);
            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();
                //3.封装成DatagramPacket 包裹,需要指定目的地
                DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
                        new InetSocketAddress(toIP, toPort));
                //4.发送包裹send(DatagramPacket p)
                client.send(packet);
                if (data.equals("bye")) {
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //5.释放资源
        client.close();
    }
}

使用面向对象封装:接收端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class TalkReceive implements Runnable {
    private DatagramSocket server;
    private String from;
    public TalkReceive(int port,String from){
        this.from=from;
        try {
            server=new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
        while(true) {
            //2.准备容器 封装成DatagramPacket 包裹
            byte[] container = new byte[1024 * 60];
            DatagramPacket packet = new DatagramPacket(container, 0, container.length);
            //3.阻塞式接收包裹receive(DatagramPacket p)
            try {
                server.receive(packet);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //4.分析数据
            // byte[] getData()
            //        getLength()
            byte[] datas = packet.getData();
            int len = packet.getLength();
            String data=new String(datas,0,len);
            System.out.println(from+":"+data);
            if(data.equals("bye")){
                break;
            }
        }
        //5.释放资源
        server.close();
    }
}

对象:学生

public class TalkStudent {
    public static void main(String[] args){
        new Thread(new TalkSend(6666,"localhost",9999)).start();//发送
        new Thread(new TalkReceive(8888,"老师")).start();//接收
    }
}

对象:老师

public class TalkTeacher {
    public static void main(String[] args){
        new Thread(new TalkReceive(9999,"学生")).start();//接收
        new Thread(new TalkSend(7777,"localhost",8888)).start();//发送
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值