【Java】day24--Udp通信、Tcp通信

本文介绍了Java中UDP和TCP通信的基本概念、特点以及应用场景。UDP协议无连接、速度快但不可靠,适用于对实时性要求高的场景如视频会议。TCP协议面向连接、可靠,适合传输大量数据,如QQ文件传输。内容涵盖了两种协议的Socket类和数据包处理。
摘要由CSDN通过智能技术生成

(一)Udp通信

网络通讯协议:
    udp协议
    tcp协议
在java中不管是用哪种协议通信,计算机与计算机之间的通信都统称为Socket(插座)通信,通信的两端 计算机都必须要安装上Socket。
在不同的协议下应该用不同的Socket.

udp协议的特点
    1.将数据及其源和目的封装为数据包,不需要建立连接。
    2.每个数据包大小限制在64k中,基于数据包进行传输。
    3.因为无连接,所以不可靠(会出现数据丢失)。
    4.因为不需要建立连接,所有速度快。
    5.udp协议不分客户端与服务器,只分发送端与接收端。
    玩游戏是udp,卡机其实是数据包丢失。
        比如:对讲机、飞Q通信、视频会议
udp通信:
    DatagramSocket(udp协议的服务类)
    DatagramPacket(数据包类)
    
DatagramPacket(byte[] buf,int length,InetAddress address,int port)
    buf:当前数据的字节数组的表现形式。
    length:字节数组的长度。
    address:发送的ip地址。
    port:端口号。

//udp的发送端
public class demo1 {

	public static void main(String[] args) throws IOException {
		//第一步:建立udp的服务
		DatagramSocket socket=new DatagramSocket();
		//第二步:准备数据,把数据封装到数据包中
		String data="这个是我的第一个udp的例子!";
		byte[] buf=data.getBytes();
		DatagramPacket packet=new DatagramPacket(buf, buf.length,InetAddress.getLocalHost(),9090);//InetAddress.getByName(ip地址)指定接收端ip地址
		//第三步:调用udp的服务,发送数据
		socket.send(packet);
		//第四步:关闭资源(释放端口号)(io中关闭资源是释放资源文件)
		socket.close();
	}
}
//先启动接收端,再启动发送端
//udp服务的接收端
public class demo2_receiver {
		
	public static void main(String[] args) throws IOException {
		//第一步:建立udp的服务,并且压迫监听一个端口
		DatagramSocket socket=new DatagramSocket(9090);
		//第二步:准备一个空的数据包
		byte[] buf=new byte[1024];
		DatagramPacket packet=new DatagramPacket(buf,buf.length);
		//第三步:调用udp的服务接收数据包,数据其实是存入了字节数组中,数据包依赖于字节数组存储数据。
		socket.receive(packet);//receive()方法是一个阻塞型方法,如果没有接收到数据,会一直等待下去
		//Scanner的next方法是阻塞型方法,只有接收到数据才会继续进行,否则会一致等待
		System.out.println(packet.getAddress().getHostAddress()+"接收端接收到的数据:"+new String(buf,0,packet.getLength()));//getLength是获取本次接收到的字节个数);
		//packet.getAddress().getHostAddress()获取到发送方的ip地址   getAddress是获取对方的IP地址对象 getHostAddress()获取ip地址
		//第四步:关闭资源
		socket.close();
	}	
}

udp协议可能导致数据丢失的情况:
    1.带宽不足。
    2.cpu处理能力不足。

(二)Tcp通信

tcp协议的特点:
    1.面向连接,在传输数据之前一定要建立连接,tcp的客户端一旦建立,马上要与服务端建立连接。
    2.在连接中可以传输大量数据,基于IO流进行传输。
    3.通过三次握手机制连接,是可靠协议(保证数据传输的完整性)。
    4.因为tcp是面向连接的,所有效率稍低。
    5.tcp协议分客户端与服务端。

tcp协议下的Socket:
    Socket(客户端类)
    ServerSocket(服务端类)
比如:qq文件传输、打电话

//客户端
public class demo1 {
	public static void main(String[] args) throws UnknownHostException, IOException {
		//第一步:建立tcp的客户端服务
		Socket socket=new Socket(InetAddress.getLocalHost(),9090);
		//第二步:准备数据(基于io流传输数据),获取对应的流 通道
		String data="这是第一个tcp例子";
		//数据相对当前客户端来说是流出的,用输出流
		OutputStream outputStream=socket.getOutputStream();
		//第三步:把数据写出
		outputStream.write(data.getBytes());
		//客户端要接收服务端回送的数据
			//获取socket的输入流
		InputStream input=socket.getInputStream();
		byte[] buf=new byte[1024];
		int length=input.read(buf);
		System.out.println("客户端接收到的内容:"+new String(buf,0,length));
		//第四步:关闭资源
		//outputStream.close();//io中关闭输出流是因为占用了文件资源,这里不需要关,从socket中获得,直接关socket即可
		socket.close();
	}
}
//先启动服务端,再启动接收端
//服务端 ServerSocket
public class demo2_server {

	public static void main(String[] args) throws IOException {
		//第一步:建立tcp的服务端
		ServerSocket serverSocket=new ServerSocket(9090);
		//第二步:接受客户端的连接
		Socket socket=serverSocket.accept();//accept是阻塞型方法,没有客户端与其连接时,一直等待下去。
		//第三步:获取对应的输入流通道
		InputStream inputStream=socket.getInputStream();
		//第四步:通过输入流通道读取数据
		byte[] buf=new byte[1024];
		int length=inputStream.read(buf);
		System.out.println("服务端接收到的数据:"+new String(buf,0,length));
		//服务端给客户端回送数据
			//获取socket的输出流
		OutputStream output=socket.getOutputStream();
		output.write("客户端辛苦啦。。".getBytes());
		//第五步:关闭资源
		serverSocket.close();
	}
}

练习:

/*
一个服务端可以与多个客户端连接。
需求:编写一个服务端可以与多个客户端进行连接,客户端一旦连接成功,马上输送一张图片数据给客户端。
	再统计接收到的客户端数,同一个客户端只算一次。

服务端需要多线程
*/
//多线程服务端 提供图片
public class demo3 extends Thread{

	Socket socket;
	static HashSet ips=new HashSet();
	public demo3(Socket socket) {
		this.socket=socket;
	}
	@Override
	public void run() {
		try {
			//第一步:建立tcp服务端的服务
			//ServerSocket serverSocket=new ServerSocket(9090);
			//第二步:接收用户的请求连接
			//Socket socket=serverSocket.accept();
			//第三步:获取Socket输出字节流(服务端输出图片)
			OutputStream socketOut=socket.getOutputStream();
			//第四步:获取文件的输入流,读物文件的数据,把文件数据写出给客户端
			FileInputStream fileInputStream=new FileInputStream("E:\\1.jpg");
			byte[] buf=new byte[1024];
			int length=0;
			while((length=fileInputStream.read(buf))!=-1) {
				socketOut.write(buf,0,length);
			}
			String ip=socket.getInetAddress().getHostAddress();//获取到对方(接收方)的ip地址
			if(ips.add(ip)) {//如果可以存储到集合中,意味着这是一个新的ip地址
				System.out.println("恭喜"+ip+"下载成功、、");
				System.out.println("当前下载的人数:"+ips.size());
			}
				//第五步:关闭资源
			fileInputStream.close();
			socket.close();//每个socket都会占用端口,用完需关闭
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) throws IOException {
		//第一步:建立tcp服务端的服务,只需要一个服务端对象
		ServerSocket serverSocket=new ServerSocket(9090);
		while(true) {
			Socket socket=serverSocket.accept();//不断地接收用户的连接请求
			new demo3(socket).start();//如果产生了一个Socket就意味着有一个客户与服务端连接,马上开启一个线程为其服务
		}
	}
}
//客户端接收图片
public class demo4 {

	public static void main(String[] args) throws IOException {
		//建立tcp的客户端服务
		Socket socket=new Socket(InetAddress.getLocalHost(),9090);//客户端写的是本机
		//获取socket的输入流对象
		InputStream inputStream=socket.getInputStream();
		//建立一个文件的输出字节流对象
		FileOutputStream fileOutputStream=new FileOutputStream("E:\\小猫.jpg");
		//边读边写
		byte[] buf=new byte[1024];
		int length=0;
		while((length=inputStream.read(buf))!=-1) {
			fileOutputStream.write(buf,0,length);
		}
		//关闭资源
		fileOutputStream.close();
		socket.close();
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值