Java学习笔记之网络编程(一):UDP

package com.network.udp.demo;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import org.junit.Test;

/*

网络编程:主要用于解决计算机与计算机(手机、平板...)之间的数据传输问题;

网络编程:不需要基于html页面就可以达到数据之间的传输;比如:飞秋、QQ、微信。。。
网页编程:就是要基于html页面的基础上进行数据交互的;比如:ao(办公自动化)、高考报考系统。。。

	Java方向:
		web开发:网络编程几乎用不到;
		Android:网络编程很常用;
		
计算机网络:分布在不同地域的计算机通过外部设备链接起来达到了消息互通、资源共享的效果,就称作为一个计算机网络;

网络通讯的三要素:
	1、IP地址:通过IP地址找到目标主机;
	2、端口号:通过端口号找到是哪一个应用程序;
	3、通讯协议:通过协议规范数据的传输;

IP地址:本质是由一个32位的二进制数据组成的;但是32位数据太难记忆,于是后来为了方便记忆,就把IP地址分成了
	4份,每份8位,即2^8 = 0~255,也就是说每位最大为255;
	192.168.1.120
	00000000-00000000-00000000-00000000

IP地址由两部分组成:网络号 + 主机号;
子网掩码:255.255.255.0;前面三个255表明网络号有三个,主机号有一个;

IP地址分类:
	A类地址:一个网络号 + 三个主机号;这就意味着一个A类的IP地址就可以配 2^24 个主机;政府单位用的;
	B类地址:两个网络号 + 两个主机号;也就是说一个B类的IP地址可以配 2^16 个主机;事业单位用的(学校、银行...);
	C类地址:三个网络号 + 一个主机号;一个C类IP地址可以配 2^8 个主机;私人用的;
	
	IP类:InetAddress;
		
		常用方法:
			getLocalHost():获取本地的IP地址对象;
			getHostAddress():获取IP地址的字符串表示;
			getHostName():获取本地的主机名;
			
			getByName():根据一个主机名获取一个IP地址对象;
			
			
端口号:没有类进行描述,因为他仅仅是一个标识符;
	端口号范围: 0 ~ 65535
	公认端口:0 ~ 1023:系统紧密的绑定了一些服务,不可以使用;
	注册端口:1024 ~ 49151:系统松散的绑定了一些服务;有些可以用;
	动态或私有端口:49151 ~ 65535:都可以使用;
	一般来说,1024 ~ 65535都可以使用,如果遇到不能用的,换一个就行了;
	
	
在java中,网络通讯也称为Socket通讯,要求通讯的两台机器必须安装Socket;	
	
网络通讯的协议:
	
	UDP:
		1、将数据及其源和目的封装成数据包,不需要建立连接;
		2、每个数据包大小不能超过64K;
		3、因为无连接,所以不可靠,数据包有可能丢失;
		4、因为需要建立连接,所以速度快;
		5、UDP通讯是不分服务端与客户端的,只分发送端和接收端;
		
		比如:对讲机,聊天软件,游戏...
		
	UDP协议下的Socket:
		DatagramSocket:UDP服务类
		DatagramPacket:数据包类
			
		
	发送端的使用步骤:
		1、建立UDP服务
		2、准备要发送的数据,并创建数据包,将数据封装到包中
		3、调用UDP的服务发送数据包
		4、关闭资源;释放占用的端口号;
	
	
	
	TCP:
		1、面向连接,有特有的通道;
		2、连接中可以传输大量数据;
		3、通过三次握手连接机制,协议可靠;
		4、通信前必须建立连接,效率稍低;
		
		比如:打电话,文件的传输...

 */

public class Demo1Sender {
	
	@Test
	public void test1() throws Exception{
		// getLocalHost():获取本机的IP地址对象
		InetAddress ip = InetAddress.getLocalHost();
		
		System.out.println("IP地址:" + ip.getHostAddress());
		System.out.println("主机名:" + ip.getHostName());
		
		// 获取别人机器的IP地址对象
		// getByName():根据一个主机名获取一个IP地址对象;
		InetAddress inetAddress = InetAddress.getByName("LX-PC");
		System.out.println("IP地址:" + inetAddress.getHostAddress());
		System.out.println("主机名:" + inetAddress.getHostName());		
	}
	
	// UDP协议发送端
	public static void main(String[] args) throws Exception {
		
		// 1、建立UDP服务
		DatagramSocket socket = new DatagramSocket();
		
		// 2、准备要发送的数据,并创建数据包,将数据封装到包中
		String data = "UDP发送的数据";
		DatagramPacket packet = new DatagramPacket(
				data.getBytes(), 			// 发送数据内容,字节为单位
				data.getBytes().length, 	// 发送数据的字节大小
				InetAddress.getLocalHost(), // 发送目的的IP地址对象
				9090);						// 端口号
		
		// 3、调用UDP的服务发送数据包
		socket.send(packet);
		
		// 4、关闭资源;释放占用的端口号;
		socket.close();
	}
	
}

package com.network.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/*
 * UDP协议接收端
 */

public class Demo1Receive {

	public static void main(String[] args) throws IOException {
		
		// 1、创建UDP服务,监听一个端口
		DatagramSocket socket = new DatagramSocket(9090);
		
		// 2、创建数据包,准备接受数据
		byte[] buf = new byte[1024];
		DatagramPacket packet = new DatagramPacket(buf, buf.length);
		
		// 3、调用UDP服务接收数据;receive()方法是一个阻塞方法,如果没有接收到发送端发送的数据就会一直等待;
		socket.receive(packet);
		int len = packet.getLength();
		System.out.println("接受到的数据:" + new String(buf, 0, len));
		
		// 4、关闭资源
		socket.close();
		
	}
	
}

package com.network.udp.demo;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/*

使用UDP协议给feiQ发送数据

	每个网络程序都有自己所处理的特定格式的数据,如果接收到的数据不符合指定的格式,那么就会被当成垃圾数据丢弃;
	制定特定格式的数据就相当于加密;
	
	飞秋接收的数据格式:
		version : time : sender : ip : flag : content;
		版本号:	      时间:   发送人:	 IP: 发送的标识符:	发送的内容
									(聊天的标识符是32)
									
	在UDP协议中,有一个IP地址被称为广播地址,广播地址就是主机号为255地址;
	给广播IP地址发送消息的时候,在同一个网络段的机器都可以接收到信息;								

 */

public class FeiQDemo {

	public static void main(String[] args) throws Exception {
		
		// 建立UDP服务
		DatagramSocket socket = new DatagramSocket();
		
		// 准备数据,把数据封装到数据包中
		String data = getData("你好飞秋");
		DatagramPacket packet = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getByName("192.168.15.31"), 2425);

		// 调用UDP服务发送数据
		socket.send(packet);
		
		// 关闭资源
		socket.close();
	}
	
	// 拼接指定格式的数据
	public static String getData(String content){
		
		StringBuilder sb = new StringBuilder();
		sb.append("1.0:");
		sb.append(System.currentTimeMillis() + ":");
		sb.append("战国:");
		sb.append("192.168.10.1");
		sb.append("32:");
		sb.append(content);
		
		return sb.toString();
	}
	
}



UDP群聊测试:

package com.network.udp.chat;

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

/*
 * 群聊发送端
 */

public class ChatSender extends Thread {

	@Override
	public void run() {
		try{
			// 建立UDP服务
			DatagramSocket socket = new DatagramSocket();
			// 准备数据,把数据封装到数据包中
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			String line = null;
			DatagramPacket packet = null;
			while ((line = reader.readLine()) != null){
				packet = new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("192.68.69.255"), 9090);	
				// 发数据发送出去
				socket.send(packet);
			}
			// 关闭资源
			socket.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
}

package com.network.udp.chat;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

/*
 * 群聊接收端
 */

public class ChatReceive extends Thread {

	@Override
	public void run() {
		try{
			// 建立UDP服务,监听一个端口
			DatagramSocket socket = new DatagramSocket(9090);
			// 准备空的数据包存储数据
			byte[] buf = new byte[1024];
			DatagramPacket packet = new DatagramPacket(buf, buf.length);
			boolean flag = true;
			while (flag){
				// 调用UDP服务接收数据
				socket.receive(packet);
				// 通过数据包获取发送端的IP地址对象
				String ip = packet.getAddress().getHostAddress();
				System.out.println(ip + "说:" + new String(buf, 0, packet.getLength()));
			}
			// 关闭资源
			socket.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
}

package com.network.udp.chat;

public class CharMain {

	public static void main(String[] args) {
		
		ChatReceive receive = new ChatReceive();
		receive.start();
		
		ChatSender sender = new ChatSender();
		sender.start();
		
	}
	
}






猜你喜欢

转载自blog.csdn.net/qq_29331365/article/details/78264721
今日推荐