黑马程序员_【总结】_ 网络编程知识梳理_(end)

网络编程知识梳理


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

---------------------------------------------------------------------------------------------------------------------------------------------
1、InetAddress 用于获取 ip等信息
InetAddress i = InetAddress.getLocalHost();//获取---本机名称和地址
i.getHostAddress() 获取---本机地址
i.getHostName() 获取---本机名称
2、Socket: 通常所说的网络编程,数据通过两端的Socket 之间的IO进程传输
3、UDP(1、速度快 2、无连接    3、<= 64K包 4、不可靠)
4、UDP 通过DatagarmSocket   和     DatagramPacket   建立发送端和接收端
通过:send()---receive() 进行数据包的发送-接收
5、TCP (1、必须连接 2、大数据 3、可靠 4、效率稍低)
6、TCP 通过Socket    和    ServerSocket 建立服务端和客户端
7、shutdownOutput  【很关键的一步】: 指定 结束标记    相当于指定-1
8、当有多用户上传等相关类似情况时,定义上传功能为线程,通过循环接收不同的ip启动多个线程
---------------------------------------------------
【1】
1、找到对方IP
2、数据要发送到对方应用 指定的端口
3、通讯规则、协议   TCP/IP
InetAddress i = InetAddress.getLocalHost();//获取---本机名称和地址
i.getHostAddress() 获取---本机地址
i.getHostName() 获取---本机名称
InetAddress id = InetAddress.getByName("www.baidu.com");//返回的是  主机+IP的 数组转换为字符串打印:
class $1IPDemo 
{
	public static void main(String[] args) throws Exception
	{
		InetAddress i = InetAddress.getLocalHost();//获取---本机名称和地址
		System.out.println(i.toString());

		System.out.println(i.getHostAddress());//获取---本机地址
		System.out.println(i.getHostName());//获取---本机名称
		sop("--------------------------");
		InetAddress id = InetAddress.getByName("www.baidu.com");//返回的是  主机+IP的 数组转换为字符串打印:
		sop(id.toString());
		sop(id.getHostAddress());
		sop(id.getHostName());
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}
【2】
【2-1】UDP 特点
1、将数据及源和目的防装成数据包中,不需要建立连接
2、每个数据包的大小都限制在64K内
3、不需要建立连接,速度快
4,因不需要连接,是不可靠协议。
(1、无连接  2、不可靠  3、<= 64K包 4、速度快)
聊天、视频会议、桌面共享等都可以用UDP传输

【2-2】UDP 传输
1、DatagarmSocket   和     DatagramPacket 
2、建立发送端,接收端
3、建立数据包
4、调用Socket发送数据,接收数据方法。
send()发送
receive() 接收

5、关闭 Socket
---
【2-3】发送端:
1、建立 udpsocket 服务 (DatagramSocket 发送端)
2、建立 并 封装数据, (DatagramPacket(数组,发送其长度,接收地址,接收端口))
3、通过 socket 服务的发送功能,将数据包发送
4、关闭资源
class Send 
{
	public static void main(String[] args) throws Exception
	{
		//哈哈,实现了,一对一聊天。
		//创建udp 服务
		DatagramSocket ds = new DatagramSocket();

		 BufferedReader bufr =   //接收键盘录入
			new BufferedReader(new InputStreamReader(System.in));

		String line = null;
		//封装数据
		while((line = bufr.readLine())!=null){
			if("886".equals(line))
				break;
			byte [] buf = line.getBytes();

			DatagramPacket dp =  //指定数据包,数据包大小(长度),主机,端口
				new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10000);
			ds.send(dp); //很关键的一步,发送动作
		}
		ds.close();
	}
}
【2-4】接收端:
1、定义 udpsocket 服务、通常会监听一个端口,其实就是接收网络应用程序自定义数字表示(端口号)
方便与明确那写数据过来,该应用程序可以处理。
2、定义一个数据包,因为要储存接收到的字节数据
因为数据包对象中有很多功能可以提取字节数据,存入以定义好的数据包中。
3、通过 socket 服务的 receive 方法将接收到的数据存入已经定好的数据包中
4、通过数据包对象特有的功能,将这些不同是数据取出,打印在控制台上。
5,关闭资源
class Receive
{
	public static void main(String[] args) throws Exception
	{
		// 创建 udp  socket   建立断点,【并指定端口号】
		DatagramSocket ds = new DatagramSocket(10000);//

		while(true){  //循环接收 对方发送的数据
			byte [] buf = new byte[1024];//建立一个数组,用于接收拆包后数据

			DatagramPacket dp = new DatagramPacket(buf,buf.length);//通过该类特有方法,进行拆包。

			ds.receive(dp);//接收数据并给 DatagramPacket 进行拆包

			String ip = dp.getAddress().getHostAddress();//获取对方ip  

			String data = new String(dp.getData(),0,dp.getLength());//获取数据信息。  getLength()实际长度

			int port = dp.getPort();//对方端口

			sop(ip);
			sop(data);
			sop(port);
		}
		//ds.close();
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}
UDP  不需要连接、如果对方没有开启接收端,数据丢失。
【3】
【3-1】TCP 特点:
1、必须建立连接
2、大数据传输
3、通过三次握手完成连接,可靠连接
4、必须建立连接 ---效率稍低
下载使用的就是 TCP协议

【3-2
     Socktet】 --   就是通常所说的网络编程
1、Socket  就是为网络服务提供的一种机制
2、通信的两端都有Socket
3、网络通信其实就是Socket 间的通信
4、数据在两个Socket 之间通过IO传输
【3-3】TCP 传输
1、Socket    和    ServerSocket
2、建立客户端和服务端
3、建立客户端后通过 Socket 中的 IO流 进行数据的传输
4、关闭


【3-4】
演示  【 TCP 】 传输
1、tcp 分 客户端、服务端
2、 客户端对应的是 Socket
服务端对应的是 ServerSocket


客户端
------
通过查阅 socket 对象,发现给对象建立时,就可以去连接指定主机。
因为TCP 是面向连接的,所以在建立 socket 服务时
就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输。


步奏:
1、创建socket 服务,并指定要连接的主机和端口  Socket();
2、为 发送数据,应该获取 socket 流(网络流) 中的输出流。 getOutputStream();
3、//使用网络输出流 进行数据的书写
--------------------------------
class TcpClient
{
	
	public static void main(String[] args) throws Exception
	{
		//Date d=null;
		Socket s = new Socket("127.0.0.1",10005);
		
		OutputStream out = s.getOutputStream();

		out.write("美女,你在干嘛~".getBytes());
			//d =new Date();
			String de = time(new Date());
			System.out.println("\t\t"+de);
			System.out.println("\t\t\t\t美女,你在干嘛~");
		//2
		
		InputStream in = s.getInputStream();
		byte [] buf = new byte[1024];
		int len = in.read(buf);
		//3
			de = time(new Date());
			System.out.println("\t\t"+de);
		System.out.println("美女:"+new String(buf,0,len));
		s.close();
	}
	public static String time(Date d){
	
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		String de = sdf.format(d);
		return de;
	}
}
服务端
------
1、建立服务端的 socket 服务。 ServerSocket(); 并监听一个端口(指定)
2、获取连接过来的客户端对象。通过 accept(); 方法 没有连接就会等
所以,accept同  receive 同 System.in 同 Reader    都是阻塞式
3、客户端如果发过来数据,那么服务端要使用对应的客户端对象,
并获取到该客户端对象的读取流来读取发过来的数据。
4、关闭 服务端  (可选)
--------------------------
class TcpServer
{

	public static void main(String[] args) throws Exception
	{
		ServerSocket ss = new ServerSocket(10005);
		Socket s = ss.accept();

		String ip = s.getInetAddress().getHostAddress();
			//3
				String de = time(new Date());
				System.out.println("\t\t"+de);
		//System.out.println("信息来自:"+ip);

		InputStream in = s.getInputStream();
		byte [] buf = new byte[1024];
		int len = in.read(buf);

		System.out.println("帅哥:"+new String(buf,0,len));

		//2

		OutputStream out = s.getOutputStream();
			Thread.sleep(6000);//延缓几秒发送,模拟聊天嘛。
		out.write("想你啊!~".getBytes());
			
			 Date d =new Date();
			de = time(d);
			System.out.println("\t\t"+de);
			System.out.println("\t\t\t\t想你啊!~");
		s.close();
		ss.close();
	}
	public static String time(Date d){
		
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		String de = sdf.format(d);
		return de;
	}
}
服务端同 客户端很类似
一个是先发送数据,一个是接收后在发送数据


【3-4】
需求:
设定一个  服务端-- 客户端    实现多客户同时上传功能。指点为 jpg 图片
-----------
客户端:
1、建立 客户端 服务 并指定主机 和端口 socket
2、读取  读取图片的流 ,和写入网络的输出流, BufferedInputStrean--  OutputStream--getOutputStream();
3、定义数组,,动过循环读取图片数据,并写入网络输出流中
4、定义读取数据,接收 网络读取流,获取服务器的反馈信息 InputSteram  getInputStream
5、注意表示 输出流结束标记      最后关闭资源
6、发现: 指定文件不能达到多客户上传, 进行 主函数 接收一个文件地址进行 模拟多客户 上传
7、对 接收到的文件进行 判断 1、是否存在 2、是否为jpg 格式 3、是否 超大提及、
满足条件后才执行  建立客户端服务
-----------
服务端
1、建立 服务端  并指定端口 ServerSocket
1-1 获取客服端 --连接对象 accept
2、建立 读取流,,读取 获得网络流中的数据 BuferedReader    getInnputStream
3、读取完毕后,给予反馈信息  OutputStream 或者PrintWriter     getOutputStream
4、关闭。
5、发现: 即使   添加一个whlie(true)   也只能一个用户进行上传>>   多线程
线程应该初始化 就接收 一个客户端连接对象   而公共代码方法 run 方法中
6、通过在服务端 主线程中, 进行whlie(true)   添加一个匿名
new thread(new xianc(s)).start();

当 在主线程中添加上面 线程后, 主线程先执行,传入一个 A 客户端连接对象、,
建立一个A 线程,进行上传,这个时候 程序有两个线程,当执行主线程的时候,
循环 true 又进来一个 B 客户端连接对象,又创建B线程 一直循环
从而达到多线程完成上传。
//客户端
class  Client
{
	public static void main(String[] args) throws Exception
	{	//9、 对传入的 参数进行判断   只能传 一个
		if(args.length != 1 ){    
			sop("输入一个图片以及其地址");
			return;
		}
		//8、接收一个主函数参数 并封装为一个 对象
		File file = new File(args [0]);
		//10、对不合格各---种格式--进行--逐一判断。
		if(!file.exists() && file.isFile()){
			sop("路径或文件不正确");
			return;
		}
		if(!file.getName().endsWith(".jpg")){
			sop("格式不正确");
			return;
		}
		if(file.length()>1024*1024*5){
			sop(" 图片体积过大");
			return;
		}
		//11、 符合上面条件后,程序进行下一步 进行连接主机:

		//1、建立 socket  服务,并绑定 主机ip 和端口
		Socket s = new Socket("127.0.0.1",10002);
		//2、建立 读取流 读取 本地文件
		BufferedInputStream bufi = new BufferedInputStream(new FileInputStream(file));
		//3、建立 输入流  接收 网络输入流
		OutputStream out = s.getOutputStream();
		//4、 建立一个数组, 循环遍历将数据装入数组
		byte [] by = new byte[1024];
		int len = 0;
		while((len = bufi.read(by)) != -1){
			//4-1 遍历满一组数组,就将数据写入到 网络输入流中 并进行刷新发送
			out.write(by,0,len);
			out.flush();

		}
		//5、【很关键的一步】: 指定 结束标记    相当于-1
		s.shutdownOutput();
		//6、接收 服务端反馈的信息    定义一个读取流 接收  网络读取流
		BufferedReader in = new BufferedReader( new InputStreamReader(s.getInputStream()));
			
		String str = in.readLine();
		sop(str);
		//7、  关闭相关资源
		s.close();
		bufi.close();

	}
	public static void checkFile(){
	
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}


//  服务端
class  Server
{
	public static void main(String[] args) throws Exception
	{
		//1、构建 服务端 并绑定端口
		ServerSocket ss = new ServerSocket(10002);
		
		//4 循环-当有多个客户端同时上传时,会--先后-获取到不同的 客户端连接对象 从而
		//		创建出不同的线程,达到多客户同时上传的效果。
		while(true){
			//2、 获取的客户端 连接对象
			Socket s = ss.accept();
			//3、根据客户端连接对象 创建一个新的线程
			new Thread(new picThread(s)).start();
		}

	}
}

// 处理上传---线程
class picThread implements Runnable
{
	private Socket s;
	//1、把 客户端--连接对象  传入 线程 进行初始化。
	picThread(Socket s ){
		this.s = s ;
	}
	public void run(){
		int count=1;
		File file;
		//0、run方法中必须try
		try
		{
			//8、 通过根据不同客户端的不同ip 进行文件的存储,
			String ip = s.getInetAddress().getHostAddress();
			//8-1 当没有这个文件的时候:
			file = new File("D:\\TCP\\"+ip+".jpg");
			//8-2 循环:当有了这个文件后,利用计数器 递增文件名
			while(file.exists()){				
				 file = new File("D:\\TCP\\"+ip+"("+(count++)+").jpg");
			}			
			//2、创建 并接收 网络 读取流 
			InputStream in = s.getInputStream();
			//3、 创建一个输出流,并绑定一个写入的目的
			BufferedOutputStream  bufw = new BufferedOutputStream(new FileOutputStream(file));
			//4、定义数组,循环读取网络流中数据,存入数组   
			byte [] by = new byte[1024];
			int len = 0 ;
			while((len = in.read(by)) != -1){
				//4-1 每满一个数组  就写入到目的中
				bufw.write(by,0,len);
				bufw.flush();
			}
			//5  服务端 对客户端进行反馈信息   两种表现方式:
				//写入方式1
			OutputStream out = s.getOutputStream();
			out.write("上传成功!~".getBytes());

				//写入方式2
			PrintWriter pw = new PrintWriter(s.getOutputStream());
			pw.println("丫!~妈的!~");			
			//6、关闭相关资源
			s.close();
			bufw.close();
		}
		catch (Exception e)
		{
			//7、抛出 RuntimeException
			throw new RuntimeException("上传失败");
		}
		
	}
}
【4-5】
练习
需求:
客户端通过键盘录入用户名
服务端对这个用户名进行校验


如果用户存在,在服务端显示XXX 已登录
并在客户端显示XXX 欢迎回来


如果该用户不存在,在服务端显示XXX 尝试登录
并在客户端显示 XX该用户不存在


--------------
分析:


1、服务端:键值对存贮信息。
2、 客服端 :录入 用户名,  
1、流--读取键盘
2、读取流传入--网络输出流--发送
3、服务端
1、定义流 接收-网络流, 
2、获取 用户名  
3、建立读取流 读取 键值对文件 用户名
4、两个用户名,进行匹配。
5、成功返回 欢迎,等情况
class Client 
{
	public static void main(String[] args) throws Exception
	{	// 建立--客户端--绑定ip、端口
		Socket s = new Socket("127.0.0.1",10004);
		// 建立--读取流--接收--键盘录入
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));
		//建立--输出流--绑定 网络输出流--记住一定要true-否则不刷新
		PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
		// 建立--读取流--绑定--网络读取流
		BufferedReader in = 
				new BufferedReader(new InputStreamReader(s.getInputStream()));
		//限制--最多3  次登录  机会
		for(int i = 0; i<3 ; i++){
			// 获取--键盘录入信息--只有一行的--空或者ctrl+c 跳出循环 
			String line =bufr.readLine();
			if(line==null)
				break;
			// 网络输出流 --发送数据
			pw.println(line);
			// 网络读取流--获取--服务端反馈信-- 如果包含成功登陆关键字,结束循环
			String info = in.readLine();
			System.out.println("::"+info);
			if(info.contains("欢迎"))
				break;
		}
		// 关闭相关资源
		s.close();
		bufr.close();
	}
}
【5】
URL--URLConnection
openConnetion() 返回主机连接对象   -- 应用层  
该对象方法主动连接,就不用写Socket对象了。 -- 传输层






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


----------------------------------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值