java网络编程TCP和UDP

一.什么是TCP?

    TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议“面向连接”就是在正式通信前必须要与对方建立起连接。比如你给别人打电话,必须等线路接通了、对方拿起话筒才能相互通话。)也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,我们这里只做简单、形象的介绍,你只要做到能够理解这个过程即可。我们来看看这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机

A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。

    TCP协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地发往网络上的其他计算机,对可靠性要求高的数据通信系统往往使用TCP协议传输数据。

优点: 可靠,稳定,TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。

缺点: 慢,效率低,占用系统资源高。

二.什么是UDP?

面向非连接的UDP协议
“面向非连接”就是在正式通信前不必与对方先建立连接,不管对方状态就直接发送。与手机短信非常相似:你在发短信的时候,只需要输入对方手机号就OK了。
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!
UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。比如,我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送ICMP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。

优点:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多。

缺点不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。

以下所有代码都是测试方法。

InetAddress 代表网络中的某一台主机
	@Test
	public void inetAddress() throws UnknownHostException {
//		127.0.0.1  回送地址 本机
		InetAddress inet=InetAddress.getByName("127.0.0.1");
		System.out.println(inet.getHostName());
	}

TCP

客户端:

1.构建Socket实例,通过指定的远程服务器地址和端口来建立连接。

2.通过Socket实例包含的InputStream和OutputStream来进行数据的读写。

3.操作结束后调用socket实例的close方法,关闭。


服务端

1. 构建一个ServerSocket实例,指定本地的端口。这个socket就是用来监听指定端口的连接请求的。

2调用socket的accept()方法来获得下面客户端的连接请求。通过accept()方法返回的socket实例,建立了一个和客户端的新连接。

3通过这个返回的socket实例获取InputStream和OutputStream,可以通过这两个stream来分别读和写数据。

4结束的时候调用socket实例的close()方法关闭socket连接。


	//客户端
	@Test
	public void client() {
		String str="123";

		//创建客户端的socket服务。
		Socket s = null;
//		输出流
		OutputStream os = null;
//		输入流
		InputStream is = null;
		
		try {
//			指定目的主机和端口 		端口号范围:0-65535
			s=new Socket("192.168.0.56",8888);
			os=s.getOutputStream();
			//写出数据
			os.write(str.getBytes());
			s.shutdownOutput();
			//接收数据
			is = s.getInputStream();
			byte[] b=new byte[1024];
			int len;
			StringBuilder sb=new StringBuilder();
			while((len=is.read(b))!=-1) {
				sb.append(new String(b, 0, len));
			}
			System.out.println(sb.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				is.close();
			} catch (IOException e2) {
				e2.printStackTrace();
			}
			
			try {
				os.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			try {
				s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	//服务端
	@Test
	public void TCPserver() {

		//建立服务端socket服务。并监听一个端口。
		ServerSocket ss = null;
		InputStream is = null;
		OutputStream os = null;
		Socket accept = null;
		try {
//			创建服务端
			ss=new ServerSocket(8888);
//			接收客户端的连接
			accept = ss.accept();
			is = accept.getInputStream();
			byte[] b=new byte[1024];
			int len;
			StringBuilder sb=new StringBuilder();
			while((len=is.read(b))!=-1) {
				sb.append(new String(b, 0, len));
			}
//			打印
			System.out.println(sb.toString());
			//输出
			os = accept.getOutputStream();
			os.write("你好".getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				accept.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				ss.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

UDP

服务端

1. 构造DatagramSocket实例,指定本地端口。

2. 通过DatagramSocket实例的receive方法接收DatagramPacket.DatagramPacket中间就包含了通信的内容。

3. 通过DatagramSocket的send和receive方法来收和发DatagramPacket.

客户端

1. 构造DatagramSocket实例。

2.通过DatagramSocket实例的send和receive方法发送DatagramPacket。

3.结束后,调用DatagramSocket的close方法关闭。

	@Test
	public void udpServer() {
		Scanner sc=new Scanner(System.in);
			try {
//				创建一个服务端DatagramSocket,指定一个监听的端口
				DatagramSocket ds = new DatagramSocket(6789);
				DatagramPacket dp;
				while(true){
					
//				存储接收的数据
					byte[] b=new byte[1024];
					//数据包
					dp=new DatagramPacket(b, b.length);
					//接收
					ds.receive(dp);
//					获取数据长度
					int len=dp.getLength();
					System.out.println(new String(b,0,len));
//					通过数据包获取地址
					InetAddress byName = dp.getAddress();
					String str=sc.nextLine();
//					要发送放入数据
					byte[] b1=str.getBytes();
					//把数据,目标地址,端口封装成一个DatagramPacket
					dp=new DatagramPacket(b1, b1.length,byName,9876);
//							发送
					ds.send(dp);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		
	}
	@Test
	public void udpClient() {
		Scanner sc=new Scanner(System.in);
		try {
			DatagramSocket ds = new DatagramSocket(9876);
			DatagramPacket dp;
			InetAddress byName = InetAddress.getByName("127.0.0.1");
			while(true) {
				String str=sc.nextLine();
//				要发送的数据
				byte[] b=str.getBytes();
				//把数据,目标地址,端口封装成一个DatagramPacket
				dp=new DatagramPacket(b, b.length,byName,6789);
//				发送
				ds.send(dp);
//				用于存储接收的数据
				byte[] b2=str.getBytes();
//				数据包
				dp=new DatagramPacket(b2, b2.length);
//				接收
				ds.receive(dp);
//				获取数据长度
				int len=dp.getLength();
				System.out.println(new String(b,0,len));
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
			
		
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值