JAVA学习————Day36

网络编程

1.TCP协议
1.1 TCP协议简介

TCP:Transmission Control Protocol 传输控制协议,是一种面向连接、可靠的、基于字节流传输的传输层通信协议。

TCP的特点:

1、面向连接

2、可靠的传输 安全传输

3、基于字节流

4、传输的大小没有限制

1.2 java中的TCP实现

Socket:套接字 实现通信的端点

用于描述IP和端口号,是一个通信的句柄。网络通信指的就是Socket之间的通信

常用的:

1.构造函数

​ 1.无参构造

`**Socket**()` 

​ 2.有参构造:

`**Socket**(InetAddress address, int port)`  

2.常用方法

​ 1.获取内容 可以接受其他发来的内容 输入流–>读取

`**getInputStream**()`  

​ 2.写出内容 可以向其他发送消息内容 输出流—>写出

`**getOutputStream**()`  

​ 3.连接服务器 连接到服务器上

`**connect**(SocketAddress endpoint)` 

​ 4.关闭服务器

close()

ServerSocket:服务端套接字 主要用于TCP的服务端

常用的:

1.构造函数 创建实例,指定服务端端口号

ServerSocket(int port)

2.监听客户端的连接 如果没有连接,程序就阻塞在这,等待连接 返回值就是套接字

accept()

3.关闭

close()
1.3 TCP的开发步骤

1.开发服务端

1.创建ServerSocket实例,并指定端口号

2.监听客户端的连接

3.消息交互

4.关闭

​ 1.流

​ 2.套接字

​ 3.服务端套接字
示例代码:

public static void main(String[] args) throws IOException {
		//1、创建服务端实例对象,并指定端口号
		ServerSocket server=new ServerSocket(8888);
		//2、实现客户端连接的监听
		Socket client=server.accept();//阻塞监听
		System.err.println("客户端连接……");
		//3、消息交互 发送消息
		client.getOutputStream().write("郑州欢迎你".getBytes());
		//4、关闭
		client.close();
		server.close();
	}

2.开发客户端
1.实例化套接字对象,并指定服务端的IP和端口号

2.信息交互

3.关闭、销毁
示例代码:

public static void main(String[] args) throws UnknownHostException, IOException {
		//1、实例化套接字对象,并完成服务端的连接
		Socket socket=new Socket(InetAddress.getLocalHost(), 8888);
		//2、消息交互
		//接收消息
		InputStream is=socket.getInputStream();
		byte[] data=new byte[512];
		int length=is.read(data);
		System.out.println("客户端:接收服务端的消息:"+new String(data,0,length));
		//3、关闭 销毁
		is.close();
		socket.close();
	}
2.4 基于TCP实现一对一聊天

服务端

public class TalkServer {

	public static void main(String[] args) throws Exception {
		//1、实例化
		ServerSocket server=new ServerSocket(10088);
		System.out.println("豪杰已在线……等你来撩!");
		//2、监听客户端连接
		Socket socket=server.accept();
		//3、信息交互
		//获取对应的输入流和输出流 用户信息的获取和发送
		InputStream re=socket.getInputStream();
		OutputStream se=socket.getOutputStream();
		//发送默认消息
		se.write("你好,我是豪杰……".getBytes());
		//准备接受消息的数组
		byte[] data=new byte[1024];
		int len;
		//键盘录入
		Scanner scanner=new Scanner(System.in);
		//循环 聊天
		while(true) {
			System.out.println("请输入聊天内容:");
			String msg=scanner.nextLine();
			se.write(msg.getBytes());
			len=re.read(data);
			System.out.println("豪杰:"+new String(data,0,len));
		}
	}
}

客户端:

public class TalkClient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		//1、实例化客户端对象
		Socket socket=new Socket(InetAddress.getLocalHost(), 10088);
		//2、信息交互
		//获取对应的输入流和输出流 用户信息的获取和发送
		InputStream re=socket.getInputStream();
		OutputStream se=socket.getOutputStream();
		//准备接受消息的数组
		byte[] data=new byte[1024];
		int len;
		//键盘录入
		Scanner scanner=new Scanner(System.in);
		//循环 聊天
		while(true) {
			len=re.read(data);
			System.out.println("老邢:"+new String(data,0,len));
			System.out.println("请输入聊天内容:");
			String msg=scanner.nextLine();
			se.write(msg.getBytes());
		}
	}
}
V2.0 迭代升级 要求改进一问一答,实现一对一的任意聊天

服务端:

public class TalkServer {

	public static void main(String[] args) throws Exception {
		//1、实例化
		ServerSocket server=new ServerSocket(10088);
		System.out.println("***豪杰聊天***");
		//2、监听客户端连接
		Socket socket=server.accept();
		//3、信息交互
		//引入线程 实现异步通信 2个线程 一个负责 接受消息、一个负责发送消息
		//发送线程
		Thread sendThread=new Thread(new Runnable() {
			@Override
			public void run() {
				OutputStream se;
				try {
					se = socket.getOutputStream();
					//发送默认消息
					se.write("你好,我是豪杰……".getBytes());
					//键盘录入
					Scanner scanner=new Scanner(System.in);
					while(true) {
						System.out.println("请输入聊天内容:");
						String msg=scanner.nextLine();
						se.write(msg.getBytes());
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		sendThread.start();
		//接收线程 用于消息的接收
		Thread recThread=new Thread(new Runnable() {
			@Override
			public void run() {
				//获取对应的输入流和输出流 用户信息的获取和发送
				InputStream re;
				try {
					re = socket.getInputStream();
					//准备接受消息的数组
					byte[] data=new byte[1024];
					int len;
					while (true) {
						len=re.read(data);
						System.out.println("豪杰:"+new String(data,0,len));
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		recThread.start();
	}
}

客户端:

public class TalkClient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		//1、实例化客户端对象
		Socket socket=new Socket(InetAddress.getLocalHost(), 10088);
		System.out.println("***老邢聊天***");
		//2、信息交互
		//引入线程 实现任意聊天
		//接收线程 用于消息的接收
		Thread recThread=new Thread(new Runnable() {
			@Override
			public void run() {
				//获取对应的输入流和输出流 用户信息的获取和发送
				InputStream re;
				try {
					re = socket.getInputStream();
					//准备接受消息的数组
					byte[] data=new byte[1024];
					int len;
					while(true) {
						len=re.read(data);
						System.out.println("老邢:"+new String(data,0,len));
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		recThread.start();
		//发送线程 实现消息的发送
		Thread sendThread=new Thread(new Runnable() {
			@Override
			public void run() {
				OutputStream se;
				try {
					se = socket.getOutputStream();
					//键盘录入
					Scanner scanner=new Scanner(System.in);
					while(true) {
						System.out.println("请输入聊天内容:");
						String msg=scanner.nextLine();
						se.write(msg.getBytes());
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		sendThread.start();
	}
}
2. UDP协议
2.1 UDP协议简介

UDP:User Datagram Protocol 用户数据报协议。是一种不可靠,面向无连接的传输层通信协议。

UDP特点:

1.面向无连接

2.不可靠传输

3.每次传输的内容不能超过64KB

4.性能高效

UDP的不可靠传输:udp仅仅在数据报的头部,添加了复用和数据校验。

Ftp协议 底层 udp

Http协议 底层 tcp

2.2 java中的UDP实现

Java支持udp协议,对UDP进行类的封装。

1.DatagramPacket 数据报包

​ 主要是包含要发送或接收的数据。和对应数据的IP地址和端口号

数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。

常用的:

1.构造函数

​ a.接收数据的数据报包

DatagramPacket(byte[] buf, int length) 

​ b.发送数据的数据报包

DatagramPacket(byte[] buf, int length, InetAddress address, int port) 

2.获取内容

getData() 

3.设置内容

setData(byte[] buf) 

4.获取长度

getLength()

2.DatagramSocket 用来发送和接收数据报包的套接字

可以实现基于UDP协议进行通信,可以发送或者接收 对应的数据报包

常用的:

1.构造函数

DatagramSocket(int port) 

2.接收数据报包

receive(DatagramPacket p) 

3.发送数据报包

send(DatagramPacket p) 

4.关闭

close() 
2.3 UDP开发步骤

1.实例化套接字对象

2.实例化 数据报包 接收报包和发送报包

3.发送或接收内容

4.关闭销毁
示例代码:接收消息

public class UdpClient01 {
	public static void main(String[] args) throws IOException {
		//1、实例化套接字对象
		DatagramSocket socket=new DatagramSocket(8881);
		//2、实例化数据报包 用于消息的接收
		byte[] arr=new byte[1024];
		DatagramPacket rPacket=new DatagramPacket(arr, arr.length);
		//3、接收消息
		socket.receive(rPacket);
		//4、显示信息
		System.out.println("接收消息:"+new String(rPacket.getData(),0,rPacket.getLength()));
		//5、关闭
		socket.close();
	}
}

发送消息:

public class UdpClient02 {

	public static void main(String[] args) throws IOException {
		//1、实例化套接字对象
		DatagramSocket socket=new DatagramSocket(8882);
		//2、实例化 发送数据的数据报包
		byte[] arr="内涵段子".getBytes();
		DatagramPacket sPacket=new DatagramPacket(arr, arr.length,InetAddress.getLocalHost(),8881);
		//3、发送消息
		socket.send(sPacket);
		//4、关闭
		socket.close();
	}
}
2.4 基于UDP实现聊天室

需求:使用udp协议实现网络聊天室
示例代码:聊天室,转发器

public class TalkRoom {
	public static void main(String[] args) throws Exception{
		//1、创建套接字
		DatagramSocket socket=new DatagramSocket(10010);
		//2、准备集合 记录 在线的地址信息 记录端口号
		HashSet<Integer> ads=new HashSet<>();
		//3、准备发送和接收的字节数组
		byte[] sarr=new byte[1024];
		byte[] rarr=new byte[1024];
		//4、实例化 数据报包
		DatagramPacket sdata=new DatagramPacket(sarr, sarr.length);
		DatagramPacket rdata=new DatagramPacket(rarr, rarr.length);
		String msg;
		System.out.println("*******聊天室*******");
		//5、循环 接收和转发消息
		while(true) {
			//接收消息
			socket.receive(rdata);
			//获取接收到的消息
			//校验当前客户端是否已经记录
			if(!ads.contains(rdata.getPort())) {
				ads.add(rdata.getPort());
			}
			//获取接收的消息
			msg=new String(rarr,0,rdata.getLength());
			System.err.println("聊天室:"+msg);
			//转发消息 其他人 不包含发消息的人
			for(Integer port:ads) {
				if(port!=rdata.getPort()) {
					sdata.setAddress(InetAddress.getLocalHost());
					sdata.setPort(port);
					sdata.setData(msg.getBytes());
					socket.send(sdata);
				}
			}
		}
	}
}

聊天室客户端:

public class TalkClient01 {
	public static void main(String[] args) throws SocketException {
		//1、实例化套接字
		DatagramSocket socket=new DatagramSocket(9001);
		//2、线程池 多线程进行聊天 1个线程负责发送消息 1个负责接收消息
		ThreadPoolExecutor tpe=new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
		//3、发送线程
		tpe.execute(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//1.数据报包
				byte[] arr=new byte[1024];
				DatagramPacket sdata;
				try {
					sdata = new DatagramPacket(arr, arr.length,InetAddress.getLocalHost(),10010);
					String m;
					Scanner scanner=new Scanner(System.in);
					while(true) {
						System.out.println("我说 :");
						m=scanner.nextLine();
						//设置发送消息
						sdata.setData(m.getBytes("UTF-8"));
						//发送消息
						socket.send(sdata);
					}
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		//4、接收线程
		tpe.execute(new Runnable() {
			@Override
			public void run() {
				//1.实例化数据报包 
				byte[] arr=new byte[1024];
				DatagramPacket rdata=new DatagramPacket(arr, arr.length);
				while(true) {
					try {
						//接收消息
						socket.receive(rdata);
						System.out.println("别人说:"+new String(arr,0,rdata.getLength()));
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
				
			}
		});
	}
}

示例代码:聊天室客户端02

public class TalkClient02 {
	public static void main(String[] args) throws SocketException {
		//1、实例化套接字
		DatagramSocket socket=new DatagramSocket(9002);
		//2、线程池 多线程进行聊天 1个线程负责发送消息 1个负责接收消息
		ThreadPoolExecutor tpe=new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
		//3、发送线程
		tpe.execute(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//1.数据报包
				byte[] arr=new byte[1024];
				DatagramPacket sdata;
				try {
					sdata = new DatagramPacket(arr, arr.length,InetAddress.getLocalHost(),10010);
					String m;
					Scanner scanner=new Scanner(System.in);
					while(true) {
						System.out.println("我说 :");
						m=scanner.nextLine();
						//设置发送消息
						sdata.setData(m.getBytes("UTF-8"));
						//发送消息
						socket.send(sdata);
					}
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		//4、接收线程
		tpe.execute(new Runnable() {
			
			@Override
			public void run() {
				//1.实例化数据报包 
				byte[] arr=new byte[1024];
				DatagramPacket rdata=new DatagramPacket(arr, arr.length);
				while(true) {
					try {
						//接收消息
						socket.receive(rdata);
						System.out.println("别人说:"+new String(arr,0,rdata.getLength()));
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值