黑马程序员--网络通讯

网络编程

---------------------------

网络通讯三要素:

要素一---IP地址:通常一个IP地址是由4个字节组成(IP V6除外),每个字节最大为255;

              Java中用于操作ip对象的类是java.net包中的InetAddress类,该类没有构造函数,

是通过里面的静态方法来获得InetAddress实例对象;

代码演示:

import  java.net.*;
class  IPDemo{
	public  static  void  main(){
		//通过getLocalHost()静态方法获取InetAddress实例对象;
		InetAddress i  =  InetAddress.getLocalHost(); 
 		System.out.println(i.toString());
		System.out.println(i.getHostAddress());   //输出主机的ip地址;
		System.out.println(i.getHostName());     //输出主机名;
		//通过getByName()静态方法获取InetAddress实例对象;
		InetAddress  ia  =  InetAddress .getByName(“www.baidu.com”);
		System.out.println(ia.getHostAddress());   //输出主机的ip地址;
		System.out.println(ia.getHostName());     //输出主机名;
	}
}

要素二---端口号:此处所说的端口号是指系统内的逻辑端口,而不是物理端口;

        举个例子:电脑中安装的既有QQ还有飞秋,那么运行QQ和飞秋后,为了保证QQ之间的数据的

彼此传输,不会发到飞秋上,在电脑内部各自还有一个标示号码,那就是端口号;如果说IP地址是

一个大厦的地址,那么端口号就是大厦中各个房间的号码!

       端口号有效范围是0~65535,但是其中的0~1024被系统保留,所以我们使用时要避开这个范围

的端口号,以免发生不必要的错误;

要素三---传输协议:较常用的传输协议有TCP协议和UDP协议;

       UDP传输协议的特点:

1、  面向无连接;

2、  数据需要被封装在包中,而且包的大小限制在64K内;

3、  由于是无连接的,所以会有可能发生丢包的情况;、

4、  传输速度快;

TCP传输协议的特点;

1、  建立连接,形成传输数据通道;

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

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

4、  由于必须建立连接,所以效率较UTP要低一点;

---------------------------

网络编程(Socket:

Socket:插座,也叫做套接字;

a、  Socket就是为网络服务提供的一种机制;

b、  通信的两端都有Socket;

c、  网络通信其实就是Socket之间的通信;

d、  数据在两个Socket之间通过IO传输;

----------------------------------------------------------------------------------------------------------------------

UDP发送端

       Java.net包中的DatagramSocket类是用来发送和接受数据报包的插座,通过使用他来发送和接收

数据报包(DatagramPackage)来实现两个通信端之间的数据传输;

需求;将一段文字数据通过UDP传输方式发送出去;

       思路:

1、建立UDP的Socket服务,可以不指定端口,由系统自行分配;

2、提供数据,封装到包中;

3、通过Socket的发送功能讲数据发送出去;

4、关闭资源,因为前面的操作调用了系统底层资源,比如:网卡;

代码演示:

import   java.net.*;
class  UdpSend{
	public  static  void  main(String[]  args){
		//建立Socket服务,端口由系统自行分配;
		DatagramSocket  ds = new  DatagramSocket();   
		byte[]  data = “udp  ge  mer  lai  la ”.getBytes();
		//将数据封装在包中,同时在包上写上包的大小,包送到哪里!
		DatagramPackage  dp  =  new DatagramPackage(data,  
					data.length();
					InetAddress.getByName(“192.168.1.254”);  
					//目的地址的IP
					10000   	//目的地址的端口
					);
		ds.send(dp);      //通过send()将数据发送出去;
		ds.close( );       //关闭底层资源;
	}
}

        如果发送端不指定端口,系统自动会随机自行分配,使用一次后,系统会顺延从新分配,

不会继续使用上一次使用的端口,因为有可能上一次使用后还没有释放!


UDP接收端:

需求:将刚才UDP发送端发送的数据接收进来,并进行处理;

思路;

1、 定义UDP的Socket服务,并需呀监听UDP发送端的数据的目的端口;

2、 定义一个空的数据报包,来存储接收到的字节数据;

3、 通过Socket的receive()将接收到的数据储存到定义好的数据报包中;

4、 通过数据报包中的特有方法将数据取出,并打印至屏幕;

5、 关闭底层资源;

代码演示:

import  java.net.*;
class  UdpReceive{
	public  static  void  main(String[]  args){
		//定义一个Socket服务点,并监听10000端口!
		DatagramSocket  ds = new  DatagramSocket(10000);
		byte[ ]  buf  = new  byte[1024];   //用于接存储数据;
		DatagramPackage  dp  =  new  DatagramPackge(buf,buf.length);
		ds.receive(dp);    //将接收的数据存储到定义的数据报包中;

		//通过数据报包的方法接收其中的数据;
		String  ip  =  dp.getAddress().getHostAddress();  //获取寄信人的地址
		String  data = new String(dp.getData(),0,dp.getLength());
		int  port = dp.getPort();             //获取寄信人的端口!
		System.out.println(ip+“:”+data+“:”+port);
		ds.close();       //关闭资源;
	}
}

UDP 键盘录入数据:

import  java.net.*;
import  java.io.*;
class  UdpSend2{
	public  static  void  main(){
		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();   //将键盘录入的数据变成一个字节数组;
			DatagramPackage  dp = new  DatagramPackage(buf,
						buf.length,
						InetAddress.getByName(“192.168.1.254”),
						10001);   //将字节数据封装在包中;
			ds.send(dp);         //通过send()将数据发送出去;
		}
		ds.close();
	}
}
class  UdpRece2{
	public  static  void  main(String[]  args){
		DatagramSocket  ds  =  new  DatagramSocket(10001);   
		//建立Socket服务,并监听10001端口
		while(true){ 
			byte   buf  = new  byte[1024];   //建立字节数组,用于接存储数据;
			DatagramPackage  dp  =  new  DatagramPackge(buf,buf.length);
			ds.receive(dp);                  //通过receive()方法来接收数据;
			System.out.println(new String(dp.getData(),0,dp.getlength()));
							//通过getData()将包中的数据取出来;
		}	
	
	}
}

小知识点:如果将主机的ip地址写成192.168.1.255,那么整个192.168.1.1~192.168.1.254段中的电脑

只要也监听了相应的端口,那么都可以收到数据!所以192.168.1.255又被称为广播地址;而192.168.1.0

是整个段的地址,是不可以被单个主机获取的!

----------------------------------------------------------------------------------------------------------------------------------------

TCP传输:

       tcp分客户端Socket服务端ServerSocket,由于tcp依赖于连接成功,所以在连接之初需要指定要连接

的主机和端口,只有连接成功,才可以彼此之间通信;

客户端的模式如下:

import  java.io.*;
import  java.net.*;
class  TcpClient{
	public  static void main(String[]  args){
		//创建Socket服务的客户端,并指定目的主机的IP和相应端口;
		Socket  s = new  Socket(“192.168.1.254”,10003);
		//为了发送数据,需要获取Socket服务中的输出流;
		OutputStream  out = s. getOutputStream();    
		//铜过getOutputStream()来获取输出流
		out.write(“tcp ge mer lai la ”.getBytes());  //通过输出流将数据写到服务端去;
		s.close();
	}
}

小知识点:其实在定义Socket时,可以先不用指定目的主机的IP和端口,而是在后面想要连接主机时

                     通过connect(SocketAddress  endPoint)方法来连接!

----------------------------------------------------------------------------------------------------------------------------------------

服务端的模式如下:


import  java.io.*;
import  java.net.*;
class  TcpServer{
	public  static  void  main(String []  args){
		ServerSocket  ss = new ServerSocket(10003); //建立服务端,并监听10003端口
		Socket s = ss .accept();   //通过accept()来接收连接过来的客户端对象;
		InputStream  in = s.getInputStream();    
		byte[]  buf = new  byte[1024];
		int  len = in.read(buf);
		System.out.println(new  String(buf, 0 , len));
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(“ip”+ip);
		s.close();              //断开客户端以节省资源;
	}
}                //在实际使用中需要先打开服务端,否则客户端连不上;

小知识点:我们知道服务端是可以连接多个客户端的,但是连接太多的客户端有可能服务端的处理器

                     处理不过来,所以我们有必要限制服务端连接的客户端的数量!我们可以通过在创建服务端

                     时向其构造函数传递一个参数backlog来限定客户端的上限!

------------

浏览器客户端----自定义服务端

       用我们平时上网的IE浏览器作为客户端,然后我们自己编写一个服务端来为客户端服务。在使用时只

需要在IE浏览器的地址栏中输入服务端的ip和相应端口,服务端就可以将数据发到浏览器中!

------------

浏览器客户端----Tomcat服务器

       用我们平时上网的IE浏览器作为客户端,然后连接Tomcat服务器中的某一个html文件,然后就可以将

文件中的数据显示在浏览器的界面上;(默认端口是:8080)

------------

自定义浏览器----Tomcat服务器

       我们自己编写一个客户端程序,然后连接Tomcat服务器中的html文件,我们编写的这个访问Tomcat服务

器的客户端程序必须带有一个请求数据头,同时请求数据头和正文之间必须空一行!其代码形式如下:

import java.net.*;
class MyIE {
	public static void main(String[] args)throws Exception {
		Socket s = new Socket("192.168.1.254",8080);
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		//下面部分为请求数据头!
		out.println("GET /myweb/demo.html HTTP/1.1");
		out.println("Accept: */*");
		out.println("Accept-Language: zh-cn");        
		out.println("Host: 192.168.1.254:11000");
		out.println("Connection: closed"); 
		//上面部分为请求数据头;
		
 		//此处必须空一行!
		out.println(); 
	       BufferedReader  bufr = new  BufferedReader( new 
					InputStreamReader(s.getInputStream()));
	       String line = null;
	       while((line=bufr.readLine())!=null){     //获取Tomcat服务器返回的数据;
		        System.out.println(line);
		}
		s.close();
	}
}

        同时在Dos命令行中的正式文本数据的前面还会有一段相响应数据头,这个数据头在IE浏览器中是看

不见的。因为IE浏览器是应用层的,他会将这个响应数据头拆掉,在网页上只显示正文数据;而我们使用

的Dos命令行是在传输层,他没有哪个功能将这个相应数据头拆掉,所以在形式上就多了一个响应数据头

--------------------------------------------------------

自定义图形化界面浏览器----Tomcat服务器

       我们通过GUI技术制作一个图形化界面的浏览器作为客户端去链接Tomcat服务器,需要在地址栏中

写上访问的主机的IP,端口,文件的路径,然后将地址栏中的文本数据经过一系列复杂的字符串操作,

从而得到要使用的IP,端口,文件路径。这种对于地址栏中文本数据的解析过程太麻烦了,所以Java的

net包中提供了URL这个类。该类中有专门针对地址栏中文本数据的操作方法,可以很easy的获得IP,

端口,文件路径等信息!

-----------------------------------------------------------

URL统一资源定位符

      他的作用就是专门获取浏览器地址栏中的文本数据,然后通过内部封装的方法获取需要的数据!

下面我们来演示他的具体使用:

private void showDir()throws Exception{
	ta.setText("");
	String urlPath = tf.getText();   //获取浏览器地址栏中输入的文本数据;
	//比如我们在浏览器的地址栏中写入了这样的数据:
	//http://192.168.1.254:8080/myweb/demo.html?name=zhangsan&age=19
	URL url = new URL(urlPath);   //将数据传给URL;
	String  protocol  =  url.getProtocol();   //获取传输协议;
	String  host = url.getHost();     //获取主机,粉色部分;
	int  port  =  url.getPort();     //获取端口;
	String  path  = url.getPath();   //获取路径;
	String  query = url.getQuery();  //获取参数部分!
	URLConnection conn = url.openConnection();	
	//获取远程连接的对象;不需要再建立Socket服务了!
	InputStream in = conn.getInputStream();   //获取输入流;
	byte[] buf = new byte[1024];
	int len = in.read(buf);
	ta.setText(new String(buf,0,len));
}

从上面的代码中我们可以看出:

        使用URL可以很方便的将地址栏中输入的数据中进行针对性的抽取,简化我们的操作









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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值