黑马程序员——网络编程

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

第一讲 网络编程概述

1、网络模型:OSI参考模型和TCP/IP参考模型


应用层为:FTP和HTTP协议等,传输层为:UDP和TCP等,网际层为:IP。

2、网络通信三要素:IP地址,端口号,传输协议

AIP地址

        a、它是网络中的设备标识

        b、不易记忆,可用主机名表示,两者存在映射关系

        c、本机回环地址:127.0.0.1,主机名为:localhost

IP地址:java中对应的是InetAddress类,存在于java.net包中。

InetAddress类:

     (一)无构造函数,可通过getLocalHost()方法获取InetAddress对象,此方法是静态的,返回本类对象。

                  InetAddress i = InetAddress.getLocalHost();

     (二)方法:

                1static InetAddress getByName(String host):获取指定主机的IP和主机名。(最好用ip地址去获取,主机名需要解析)

                2static InetAddress[] getAllByName(String host):在给定主机名的情况下,根据系统上配置的名称服务返回IP地址所组成的数组。返回对象不唯一时,用此方法。

                3String getHostAddress():返回IP地址字符串文本形式,以IP地址为主。

                4String getHostName():返回IP地址主机名。

     (三)如何获取任意一台主机的IP地址对象:

                1)功能:返回InetAddress对象

                2)对于任意主机,需要指定传入主机名的参数

注意:如果IP地址和对应的主机名,这种映射关系没有在网络上,就不会解析成功,返回的还是指定的IP

B、端口号:

        a、用于标识进程的逻辑地址,不用进程的标识。

        b、有效端口:0 ~65535,系统使用或保留的端口是:0~ 1024

C、传输协议:

        即通信规则,包含TCPUDP协议

UDP

        是面向无连接,明确了对方的端口,无论在不在网上,只管传输,不在就会丢失数据。只求速度,应用于网络视频会议和聊天等应用程序中。

协议特点:

         a、面向无连接,即将数据及源和目的封装成数据包中,不建立链接的发送

         b、每个数据包的大小限制在64K之内

         c、因无连接,是不可靠的协议

         d、不建立连接,速度快。

TCP

        是面向连接的,必须连接成功才能传输数据,应用于下载等程序上

协议特点:

         a、面向连接,在建立连接后,形成传输数据的通道

         b、在连接中进行大数据量的传输

         c、通过三次握手完成连接,是可靠的协议

         d、必须建立连接,效率稍慢

三次握手:第一次本方发送请求,第二次对方确认连接,第三次本方再次确认连接成功。

3、通信的步骤:

        1)找到IP地址

        2)数据要发送到对象指定应用程序,为标识这些应用程序,所以给这些网络应用程序都用数字标识,为方便称呼这个数字,叫做端口,即逻辑端口。

        3)定义通信规则,称之为协议。国际组织定义了通用协议,即TCP/IP

注意:必须要有数字标识才能将数据发送到应用程序上。



UDP有发送端和接受端,有两大类,DatagramSocket、DatagramPacket

步骤:

(1)建立发送端和接收端
(2)建立数据包
(3)调用Socket的接收发送方法
(4)关闭Socket
注意:发送端和接收端是两个独立的运行程序
UDP发送端演示
DatagramPacket(byte[] buf, int length, InetAddress address, int port)  
构造数据报包,用来将长度为  length  的包发送到指定主机上的指定端口号。

public static void UDPsendDemo() throws IOException {
		System.out.println("发送端");
		/*
		 * 创建UDP传输的发送端:
		 * 1.建立UDP的Socket服务
		 * 2.将要发送的数据封装到数据包中
		 * 3.用UDP的Socket服务将数据包发送出去
		 * 4.关闭Socket服务
		 */
		//建立UDP的Socket服务,使用DatagramSocket对象
		DatagramSocket ds = new DatagramSocket();
		//不指定端口号,发送端,就是随机的
		
		//数据封装成包
		String str = "udp发送";
		
		//使用DatagramPacket将数据封装到该对象的包中
		byte[] by = str.getBytes();
		DatagramPacket dp = new DatagramPacket(by,by.length,InetAddress.getByName("127.0.0.1"),6534);
		
		//通过UDP的Socket服务将数据包发送出去,send方法
		ds.send(dp);
		ds.close();
	}
UDP接收端演示

public static void UDPreceiveDemo() throws IOException {
		//接受端
		System.out.println("接收端");
		/*
		 * 创建UDP传输的接收端:
		 * 1.建立UDP的Socket服务,因为要接收数据,必须要明确端口号
		 * 2.创建数据包,用于存储接收到的数据,以便于用数据包的方法解析这些数据
		 * 3.使用Socket服务的receive方法接收的数据存储到数据包中
		 * 4.通过数据包中的方法解析包中数据
		 * 5.关闭
		 */z
		//建立UDP的Socket服务,使用DatagramSocket对象
		DatagramSocket ds = new DatagramSocket(6534);//接收端口6534
		
		//创建数据包
		byte[] buf = new byte[1024];
		DatagramPacket dp = new DatagramPacket(buf, buf.length);
		
		//使用接收方法将数据存储到数据包
		ds.receive(dp);//注意该方法是阻塞式的
		
		//使用数据包对象的方法,解析其中的数据,如:地址、端口、内容
		String ip = dp.getAddress().getHostAddress();//获取ip地址字符串
		
		int port = dp.getPort();//获取端口
		
		String datatext = new String(dp.getData(),0,dp.getLength());//将数据封装成字符串对象
		
		System.out.println("ip:"+ip+"port : "+port+"data:"+datatext);
		
		//关闭
		ds.close();
	}</span>

基于多线程模拟简单的QQ聊天程序

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

class Receive implements Runnable{
	private DatagramSocket ds;
	
	public Receive(DatagramSocket ds){
		this.ds = ds;
	}
	public void run()
	{
		try {
			while(true){
				byte[] buf = new byte[1024];
				DatagramPacket dp = new DatagramPacket(buf, buf.length);
				
				ds.receive(dp);
			
				String ip = dp.getAddress().getHostAddress();
				
				int port = dp.getPort();
				
				String datatext = new String(dp.getData(),0,dp.getLength());
				if(datatext.equals("over")){
					System.out.println("ip:"+ip+"port : "+port+"退出聊天室");
				}
				else{
					System.out.println("ip:"+ip+"port : "+port+"data:"+datatext);
				}
				
			
				}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}

class Send implements Runnable{
	private DatagramSocket ds;
	public Send(DatagramSocket ds){
		this.ds = ds;
	}
	public void run()
	{
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			String line = null;
			while((line = br.readLine())!=null){
				
				byte[] buf = line.getBytes();
				DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.255"),6534);
				//IP的有效位是0-254,255是广播,也就是127.0.0,这一IP字段上所有存活的电脑都可以接收到我发的信息
				ds.send(dp);
				if("over".equals(line))break;
			}
			ds.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}
public class Main {
	public static void main(String[] args) throws IOException{
		
		DatagramSocket dsend =new DatagramSocket();

		DatagramSocket dr =new DatagramSocket(6534);
		Send send = new Send(dsend);
		Receive receive = new Receive(dr);
		Thread t1 = new Thread(send);
		Thread t2 = new Thread(receive);
		t1.start(); t2.start();	
	}
}

2.TCP协议

TCP传输

Socket和ServerSocket

建立客户端和服务器端(两个独立的应用程序)

建立连接后,通过Socket中的IO流进行数据的传输

关闭Socket

TCP和UDP原理差不多,只是涉及的对象不一样


TCP客户端

Socket(String host, int port) 
创建一个流套接字并将其连接到指定主机上的指定端口

public static void TCPDemo() throws UnknownHostException, IOException {
		
		/*
		 * TCP传输,客户端建立
		 * 1.建立TCP客户端socket服务,使用SOCKET对象(建议一创建就明确目的地,要连接的主机)
		 * 2.如果连接建立成功,就说明数据传输通道已建立
		 * 该通道就是SOCKET流,是底层建立好的,因为是流,所以有输入输出,其输入输出流对象,在SOCKET获取
		 * 通过getInputStream()和getOutputStream()来获取两个字节流
		 * 3.使用输出流,将数据写出(网络)
		 * 4.关闭
		 */
		
		//建立客户端SOCKET服务
		Socket socket = new Socket("127.0.0.1",6534);//地址和端口号
		
		//获取SOCKET流中的输出流
		OutputStream os = socket.getOutputStream();
		
		//使用输出流将指定的数据写出
			os.write("tcp客户端发送信息".getBytes());
			
			socket.close();	
	}

TCP服务端
public static void TEPserveDeno() throws IOException {
		//服务端接收客户端发来的数据,并打印在控制台
		/*
		 * 建立TCP服务端
		 * 1.建立TCP服务端Socket服务,通过ServerSocket对象
		 * 2.服务端必须对外提供端口,否则客户端无法连接
		 * 3.获取连接过来的客户端对象(重点)
		 * (比如拨打10086人工,一个客户,一个服务人员,客户的数据,客户自己最清楚)
		 * 4.通过客户端对象获取Socket流兑取客户端发来的数据并打印
		 * 5.关闭资源:关闭客户端,关闭服务端
		 */
		//常见服务端对象
		ServerSocket ss = new ServerSocket(6534);
		
		//获取连接过来的客户端对象
		Socket so = ss.accept();//此方法用来获取客户端对象
		String ip = so.getInetAddress().getHostAddress();
		//通过Socket对象获取输入流,读取客户端发来的数据
		InputStream in = so.getInputStream();
		
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		String str = new String(buf,0,len);
		System.out.println("ip : "+ip+"server : "+str);
		
		so.close();//服务端一般是不关闭的
	}

注意:TCP和UDP不一样的是,必须先开启服务端,服务端不打开,客户端就无法访问,而UDP随意


第三讲 TCP协议练习

上传文本文件

public class Main {
	
	public static void main(String[] args)throws IOException{
		UpText_Client();
		UpText_Server();
	}

	public static void UpText_Server() throws IOException {
		
		ServerSocket ss = new ServerSocket(6534);
		Socket socket = ss.accept();
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		
		BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\server.txt"));
		
		String line = null;
		while((line = br.readLine())!=null){
			//if("over".equals(line))break;//*
			bw.write(line);
			bw.newLine();//*
			bw.flush();//*
		}
		
		PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
		pw.println("上传成功");
		
		br.close();
		bw.close();
		socket.close();
		ss.close();
	}

	public static void UpText_Client() throws IOException {
		
		Socket socket = new Socket("127.0.0.1",6534);
		BufferedReader br = new BufferedReader(new FileReader("c:\\data.txt"));
		PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
		String line = null;
		while((line = br.readLine())!=null){
			out.println(line);
		}
		//out.println("over");//*,开发的时候一般都是应用时间戳,做结束标记,先发给服务器一下时间戳,输入结束后,再发一次
		//socket里有方法
		socket.shutdownOutput();//告诉服务端数据写完了
		
		//读取socket流
		BufferedReader brin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		String string = brin.readLine();
		System.out.println(string);
		br.close();
		socket.close();
	}
}

*号处要注意,漏写容易造成,等待清理,客户端输入完毕后,服务端还在等待,不知道客户端已经输入完毕,阻塞,等待

第四讲 关于客户端服务端 && URL类 & URLConnection


常见的客户端和服务端

客户端:

      浏览器:IE:弹窗口,猎豹:弹窗口,多标签,争强效果

服务端:

      服务器:Tomcat:1.处理请求 2.给予应答

想让Tomcat为我们工作,那么java写的相关类类必须实现接口Serverlet

浏览器强大之处就在于解析能力,众多格式,都可以解析

服务端和客户端原理

自定义服务端

public static void main(String[] args) throws IOException {
		
		ServerSocket ss = new ServerSocket(9090);//Tomcat是8080

		Socket socket = ss.accept();
		InputStream in = socket.getInputStream();
		
		System.out.println("ip : "+socket.getInetAddress().getHostAddress());
		
		byte[] buf = new byte[1024];
		
		int len = in.read(buf);
		String text = new String(buf,0,len);
		System.out.println(text);
		PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
		out.println("你好");
		socket.close();
		ss.close();
	}

使用已有的客户端IE,了解客户端给服务端发送的什么请求?

请求行: 请求方式 /1.html 请求资源路径:http协议版本

请求消息头:属性名:属性值

请求体

模拟一个浏览器获取信息

	public static void main(String[] args) throws IOException {
		
		Socket s = new Socket("192.168.1.1",8080);//向tomcat获取,浏览器信息
		
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		
		out.println("GET / HTTP /.....");
		out.println("....");
		out.println("....");
		out.println("....");
		out.println("....");
		out.println("....");
		
		InputStream in = s.getInputStream();
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		String line = new String(buf,0,len);
		
		System.out.println(line);//得到就是本地写的html代码
		s.close();
	}
得到的应答:

应答行:http的协议版本 应答状态码 应答状态描述信息

应答消息属性。 属性名: 属性值

应答体:->上述的html源码

PS:浏览器太难写了,所以众多厂商都是应用原有的IE的内核


类URL

URL代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询

每个URL都是URI,但不是每个URI都是URL

	public static void URL_Demo() throws MalformedURLException {
	
		String strurl = "http://127.0.0.1:8080/myhtml/1.html?name=wang";
		//http://www.baidu.com/baidu?word=java,在百度地址栏搜索java
		URL url = new URL(strurl);
		System.out.println("Protocol:"+url.getProtocol());//获取主机协议
		System.out.println("Host:"+url.getHost());//获取主机名
		System.out.println("Port:"+url.getPort());//获取端口
		System.out.println("File:"+url.getFile());//获取文件
		System.out.println("Path:"+url.getPath());//获取路径部分
		System.out.println("Query:"+url.getQuery());//获取查询部分
		
	}
Protocol:http
Host:127.0.0.1
Port:8080
File:/myhtml/1.html?name=wang
Path:/myhtml/1.html
Query:name=wang
public static void URL_Demo() throws IOException {
	
		String strurl = "http://127.0.0.1:8080/myhtml/1.html?name=wang";
		URL url = new URL(strurl);
		InputStream in = url.openStream();//打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。
		/*
		 * 原理:
		 * openConnection() 
         *		返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。
		 * URLConnection conn = url.openConnection();
		 * System.out.println(connection);
		 * 底层封装完了关于url的http的解析方式,这个对象就是java内置的可以解析具体协议的对象+socket
		 * URLConnection类中
		 * 1.String str = conn.getHeaderField("Contend-Type");
		 * System.out.println(str);//应答一个文本类型的消息
		 * 然后就可以根据应答的结果,判断文本是何类型,根据指定的解析器,解析数据
		 * 实际上用的是Socket,加协议
		 * 2.InputStream in = conn.GetInputStream();同样得到1.html的应答体
		 * 
		 * 所以url.openStream()的原理就是:
		 * URLConnection conn = url.openConnection();
		 * InputStream in = conn.GetInputStream();
		 */
		
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		String str = new String(buf,0,len);
		System.out.println(str);//得到1.html的应答体,url帮助解析成html源码
		
		in.close();
	}

域名解析

在浏览器输入网址访问一台主机所做的操作:

  如输入http://61.135.169.125,可以直接连接此ip的主机,而我们一般是输入主机名:http:/www.baidu.ocm(百度主机对应的ip地址就是:61.135.169.125),那么此时浏览器做了神马操作呢?

  也就是说如何通过主机名获取IP地址,从而连接到这台主机呢?这就需要将主机名翻译成IP地址,即域名解析:DNS

  在进行访问的时候,会先在本地的hosts文件(c:\windows\system32\drivers\ext\host)中找对应的映射。若有,则直接返回请求;若无,则到公网的映射列表即DNS中找对应的映射,找到后,将主机名对应的IP地址返回给本机,本机通过这个IP地址找到对应的服务器。

示意图:

 host应用:可屏蔽一些恶意网址,即将对应的映射关系写入hosts中,将IP地址改为本机的回环地址,那么会直接找到hosts,就不会将请求发送出去了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值