Java学习笔记之网络通讯协议

收获总结

  • 加深了流用法的理解,字节字符流之间输入输出已经转换流的用法示意图
    在这里插入图片描述
  • 缓冲流是对普通流的再次包装,增加了缓冲区以增加每次读取的数据的数量。
  • 因为缓冲流是对底层流的再次封装,在缓冲流数据输出时每输出一次要使用flush()方法将缓冲区的数据强制冲入底层流中否则数据不能被写入。
  • Java的网络通讯客户端使用Socket类,生成类时需要指定服务器的IP地址和端口号,服务端使用的类为ServerSocket只需要指定端口号。
  • 网络通讯所使用的流区别于普通的流使用getInputStream()或者getOutputstream()来构造流。
  • getbyName方法的使用
    确定主机名称的IP地址,主机名称可以是字符或者文本格式的IP地址如果输入文本格式的IP地址只会检查IP地址的有效性
  • getAddress和getHostAddress的区别
    getAddress是获取主机的IP返回此InetAddress对象的原始IP地址。用于寻址。
    getHostAddress返回文本显示中的IP地址字符串。 用于输出文本。
  • bind方法的用法
DatagramSocket datagramSocket = new DatagramSocket(null);
           
datagramSocket.bind(new InetSocketAddress(5000));//使用时DatagramPacket要赋值为null
/*
public void bind​(SocketAddress addr)
          throws SocketException将此DatagramSocket绑定到特定的地址和端口。 
如果地址为null ,则系统将接收临时端口和有效的本地地址来绑定套接字。
//InetSocketAddress是SocketAddress的子类
InetSocketAddress​(int port) 创建一个套接字地址,其中IP地址为地址标识符,端口号为指定值。 
其他的构造方法
InetSocketAddress​(String hostname, int port) 从主机名和端口号创建套接字地址。  
InetSocketAddress​(InetAddress addr, int port) 从IP地址和端口号创建套接字地址。  
*/

学习笔记整理

IP地址

  • IP地址:计算机在网络上的唯 一标识符,是计算机的一种身份识别的形式。
    IP地址:
    查看本机IP地址:ifconfig
    查看网络是否连接:ping IP地址或主机名或域名
    4类:4字节,32位 , 01010101001
    6类:16节字,128位,010101010010101010
  • 本机回路地址:
    127.0.0.1 :代表当前主机
    localhost:代表当前主机

端口

  • IP地址主要用来标识网络上的唯一的一台计算机,端口是计算机中用来标识不同的应用程序,进行数据传输。
    端口的值在0-65535之间,占2个字节;一般在计算机中0-1023的端口大部分已经被操作系统或其它网络程序所占用。

InetAddress

  • Java中用来表示网络地址、端口、主机标识符等信息的一个类
    static InetAddress getLocalHost ():返回本地主机地址的InetAddress对象
    String getHostAddress( ):返回本地主机IP
    String getHostName( ):返回本地主机名称。

Java中的网络协议

TCP协议下的网络编程:

4.1、TCP协议的通讯原理

	TCP协议:面向连接,稳定的一种通讯协议,在连接之前向服务器端发送确认连接,等待服务器的响应。建立连接之后再传输数据,可靠、无数据差异的一种通讯协议。
	TCP的协议,每次连接前,都 需要经过三次握手,以保证连接的可靠性。

	典型的采用TCP协议的应用有:
			浏览网页,

4.2、TCP协议的特点:
1、面向连接
2、可靠
3、占有用资源多,资源开源大

4.3、TCP协议下的网络编程的实现
需要服务器端,也要有客户端,服务器端实现服务器端的通讯接口,客户端实现客户端的通讯接口。
都是实现不同的套接字,实现了TCP协议下的数据传输的端点。

	服务器端:
		ServerSocket类用来支持TCP协议下的服务器端的编程。	
			ServerSocket() :创建服务器端的套接字对象。
				
			ServerSocket(int port) :创建服务器端的套接字对象,并邦字指定的监听端口。
					 
			ServerSocket(int port, int backlog) 
			
			ServerSocket(int port, int backlog, InetAddress bindAddr)  

		注意:
			1、要邦定监听的端口。
			2、accept()方法,用来接收客户端的请求。	在执行时,处于阻塞状态,当监听到客户端的套接对象连接时,接收客户端的套接对对象。
			3、通过套接字对象提供的IO进行数据的传输。传输底层是IO的对象进行数据的读写。
			4、注意结束后,关闭相关资源(IO和Socket对象)。

			常用方法:
			Socket accept()  
			bind(SocketAddress endpoint) 
			ServerSocketChannel getChannel()
  • 通讯实例
服务器端的实现过程:
/*
    TCP协议下的服务器端的程序:
    实现步骤:
        1、创建服务器端的套接字对象
        2、调用accept()方法,等待客户端的连接
        3、通过Socket对象创建 IO输入与输出流对象
        4、将数据写入输入与输出流。
        5、关闭相关对象。

     */
    public static void main(String[] args) {

        try {
            //1、创建服务器端的套接字对象
            ServerSocket serversk = new ServerSocket(4001);
            System.out.println("服务器端running .........");
            // 2、
            Socket socket= serversk.accept();//服务器在此行代码处,一直阻塞直到有客户端的套接字连接。
            // 服务器端向客户端发送数据。
            //3、通过Socket创建输出流
            OutputStream outputStream = socket.getOutputStream();
            String serstr = "hello Huike";
            //创建字节输出缓冲流
            BufferedOutputStream buffer = new BufferedOutputStream(outputStream);
            //4、将服务器端传入至客户端的数据写入输出流
            buffer.write(serstr.getBytes());
           // 5、关闭相关对象。
            buffer.close();
            outputStream.close();
            
            socket.close();
            serversk.close();


        } catch (IOException e) {
            e.printStackTrace();
        }


    }		



客户端端:
	Socket类用来支持TCP协议下的客户端的编程。
	构造方法:
	Socket() 
			
	Socket(InetAddress address, int port) 
	
	Socket(InetAddress host, int port, boolean stream) 
		
	Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 
		Creates a socket and connects it to the  

常用方法:
 	bind(SocketAddress bindpoint) 

	void close() 

	void connect(SocketAddress endpoint) 

	void connect(SocketAddress endpoint, int timeout) 

	SocketChannel getChannel() 
	
	InetAddress getInetAddress() 

	InputStream getInputStream()  

	OutputStream getOutputStream()

	注意:
		1、指定连接的服务器端地址
		2、要指定通讯的端口号。

客户端的实现过程:
		
  /*
    客户端的实现过程:
    1、创建客户端的套接对象,(Socket对象)并指定服务器端的地址和通讯的端口号。
    2、通过Socket对象,创建输入与输出流
    3、发送或接收数据
    4、关闭相关资源

     */
    public static void main(String[] args) {
        try {
            // 1、创建客户端的套接对象,(Socket对象)并指定服务器端的地址和通讯的端口号。
            Socket socket = new Socket(InetAddress.getLocalHost(),4001);
            //2、创建输入流,从输入流中读取服务器端发过的数据
            InputStream inputStream = socket.getInputStream();
            byte b [] = new byte[1024];
            //将输入流转换成缓冲流
            BufferedInputStream buffer= new BufferedInputStream(inputStream);
            //  3、发送或接收数据
            int i =buffer.read(b);
            System.out.println(new String(b,0,i));
            //   4、关闭相关资源
            buffer.close();
            inputStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

UDP协议

UDP协议:是一种数据包协议,无状态(非连接型),不可靠,可能存在数据丢包的情况。协议简单、对资源开销较少
只有发达方和接受方的概念,一般应用的场景是:如聊天、视频。
每个是数据包64KB每个数据包单独寻址

  • UDP协议的网络编程:
    • 在java.net包中提供了两个类DatagramSocket和来支持数据包通信
    1. DatagramSocket类:数据包套接字类,主要是为每个数据包单独寻址和路由。
	  DatagramSocket​() 
	  //构造数据报套接字并将其绑定到本地主机上的任何可用端口。  
	  DatagramSocket​(int port) 
	  //构造数据报套接字并将其绑定到本地主机上的指定端口。  
	  DatagramSocket​(int port, InetAddress laddr) 
	  //创建一个数据报套接字,绑定到指定的本地地址。  
	  protected  DatagramSocket​(DatagramSocketImpl impl) 
	  //使用指定的DatagramSocketImpl创建一个未绑定的数据报套接字。  
	  DatagramSocket​(SocketAddress bindaddr) 
	  //创建一个数据报套接字,绑定到指定的本地套接字地址。 

 3. DatagramPacket类:数据报包,主要是为UDP协议封装数据包。  
DatagramPacket​(byte[] buf, int length) 构造一个 DatagramPacket用于接收长度为 length数据包。  
DatagramPacket​(byte[] buf, int offset, int length) 构造一个 DatagramPacket用于接收长度为 length数据包,指定缓冲区的偏移量。  
DatagramPacket​(byte[] buf, int offset, int length, InetAddress address, int port) 构造一个数据包,发送长度为 length的数据包,其中偏移量为 ioffset到指定主机上的指定端口号。  
DatagramPacket​(byte[] buf, int offset, int length, SocketAddress address) 构造一个数据报包,发送长度为 length的数据包,偏移量为 ioffset到指定主机上的指定端口号。  
DatagramPacket​(byte[] buf, int length, InetAddress address, int port) 构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。  
DatagramPacket​(byte[] buf, int length, SocketAddress address) 构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。 
  • 实现步骤
    发送方:
    1. 创建DatagramSocket数据包套接字对象
    2. 创建要发送的数据、并转换成可发送的数据、目标地址和端口号
    3. 创建DatagramPacket数据包对象,并制定发送的数据、目标地址和端口号。
    4. 通过DatagramSocket对象的send()芳芳发送数据报包对象。
    5. 关闭相关对象
    接收方:
    1. 创建DatagramSocket数据包套接字。
    2. 创建要接受的byte数组。
    3. 创建DatagramPacket数据报包对象,从套接字对象中接受发送方发送过来的数据报包。
    4. 通过receive()方法接收。
    5. 关闭相关对象
  • 实现方法
//发送方
 try {
 			//创建DatagramSocket对象
            DatagramSocket datagramSocket = new DatagramSocket();//默认是0
            String sentmsg = "hello world";
            byte[] data = sentmsg.getBytes();
			//创建DatagramPacket对象指定打包的数据和发送的地址端口号
            DatagramPacket datagramPacket = new DatagramPacket(data,data.length, InetAddress.getLocalHost(),5000);
            //将要发送的数据丢出
            datagramSocket.send(datagramPacket);
            System.out.println("发送完成!");
			//关闭相关端口
            datagramSocket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
//接收方
 try {
            //创建数据包的对象确定端口号
            DatagramSocket datagramSocket = new DatagramSocket(5000);
            //创建要接受的byte数组
            byte[] data = new byte[1024];
            //创建数据包对象
            DatagramPacket datagramPacket = new DatagramPacket(data,data.length);

            System.out.println("准备就绪准备接包!");
			//准备接包
            datagramSocket.receive(datagramPacket);//在此处出于阻塞状态,等待数据。
            System.out.println("接受到来自其他人的数据"+new String(data));
            //关闭相关对象
            datagramSocket.close();;
        } catch (IOException e) {
            e.printStackTrace();
        }
  • 循环发送实例
  • 针对发送方发送的消息,接收方给当前的发送方回复“收到”
  1. 解决接收方获取发送方的地址(IP地址) 、端口号。
 while (true) {
   //2、创建要接收数据的byte数组
    byte data[] = new byte[1024];
    //3、创建数据报包对象
    DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
    System.out.println("等待接包:");
    //4、DatagramPacket数据报包对象,从套接字对象中接收发送方发送过来的数据报包。
    datagramSocket.receive(datagramPacket);//处于阻塞
    String ip= datagramPacket.getAddress().getHostAddress();//发送方的IP地址
    int port = datagramPacket.getPort();//发送方的端口号
    String receMsg = new String(data);
    System.out.println(ip+","+port+":"+getDateToString()+" 说:"+receMsg);
    if ("end".equals(receMsg.trim())) break;
}
  1. 根据发送方的IP地址和端口,给发送回复消息
 public static void main(String[] args)  throws  IOException , SocketException{
       // 1、 创建DatagramSocket数据包套接字对象
       DatagramSocket datagramSocket = new DatagramSocket(null);
       //邦定端口号
       datagramSocket.bind(new InetSocketAddress(5000));
       while (true) {
           //2、创建要接收数据的byte数组
           byte data[] = new byte[1024];
           //3、创建数据报包对象
           DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
           System.out.println("等待接包:");
           //4、DatagramPacket数据报包对象,从套接字对象中接收发送方发送过来的数据报包。
           datagramSocket.receive(datagramPacket);//处于阻塞
            String ip= datagramPacket.getAddress().getHostAddress();//发送方的IP地址
           int port = datagramPacket.getPort();//发送方的端口号
           String receMsg = new String(data);
           System.out.println(ip+","+port+":"+getDateToString()+" 说:"+receMsg);
           //给指定的发送方回复“已读”
           String ok = "已读";
           byte okdata [] = ok.getBytes();
           //创建新的数据报包对象
           DatagramPacket sendPack = new 						
           DatagramPacket(okdata,okdata.length,datagramPacket.getAddress(),port);
           datagramSocket.send(sendPack);//将已读的数据报包对象发送至发送方
           if ("end".equals(receMsg.trim())) break;
       }
       //5关闭相关对象
       datagramSocket.close();
        System.out.println("程序退出");
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值