Java中的三种通信(TCP、UDP、URL)实例

(1)基于Socket的Tcp通信

1)客户端Socket的包含以下四个基本的步骤:

    创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。

    打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用 getOutputStream()方法获得输出流,进行数据传输。

按照协议对 Socket进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。

    关闭 Socket:断开客户端到服务器的连接,释放线路

2)服务器端程序包含以下四个基本的步骤:

    调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。监听客户端的请求。

调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。

    调用该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。

    关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。

TCP实例:


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import org.junit.Test;

//TCP实例:从客户端(Client)发送文件(实例中以照片为例)给服务端(Server),服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接。
public class testTcp3 {
	//客户端
	@Test
	public void client(){
		//1.创建Socket对象,输出流对象(输出给服务端),文件输入流对象(读取文件到客户端)
		Socket socket = null;
		OutputStream os = null;
		FileInputStream fis = null;
		//2.接收来自于服务端的信息
		InputStream is = null;
		try {
			socket = new Socket(InetAddress.getByName("127.0.0.1"),8989);//通过InetAddress的getByName()方法获取要链接的地址和端口号
			
			os = socket.getOutputStream();
			fis = new FileInputStream(new File("崔洪振367.png"));
			//3、将文件(照片)写入到客户端的字节数组中
			byte[] b = new byte[1024];
			int len;
			while((len = fis.read(b)) != -1){
				os.write(b, 0, len);
			}
			//4.要关闭socket的发送,便于服务端接收
			socket.shutdownOutput();
			//5、输入流,用于接收服务端发送的数据,并通过写入到字节,打印到控制台
			is = socket.getInputStream();
			byte[] b1 = new byte[1024];
			int length;
			while((length = is.read(b1)) != -1){
				String str = new String(b1, 0, length);
				System.out.print(str);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//6、按照顺序(先开后关)关闭所有对象和socket,要使用try-catch来处理异常
			if(is != null){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(os != null){
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(socket != null){
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	@Test
	public void server(){
		//1创建一个ServerSocket的对象
		ServerSocket so = null;
		//2调用其accept()方法,返回一个Socket的对象
		Socket s = null;
		//3、将从客户端发来的消息保存到本地
		InputStream is = null;
		FileOutputStream fos = null;
		//4、用来回复客户端的语句的对象
		OutputStream os = null;
		try {
			so = new ServerSocket(8989);
			s = so.accept();
			is = s.getInputStream();
			fos = new FileOutputStream(new File("1.png"));
			//5、写入到字节数组中
			byte[] b = new byte[1024];
			int len;
			while((len = is.read(b)) != -1){
				fos.write(b, 0, len);
			}
			//打印客户端的地址
			System.out.println("收到来自:" + s.getInetAddress().getHostAddress() + "的文件!");
			//6、将字节数组中的照片保存到本地
			os = s.getOutputStream();
			os.write("我已经收到你发送的照片!".getBytes());
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			//6、按照顺序(先开后关)关闭所有对象和ServerSocket的对象,要使用try-catch来处理异常
			if(os != null){
				try {
					so.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fos != null){
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(is != null){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(s != null){
				try {
					s.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(so != null){
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}


(2)UDP网络通信

的通信过程分为发送端和接收端。发送端与接收端是两个独立的运行程序,其中两端使用的类是一致的步骤也具有一致性,其中涉及的类为:DatagramSocket与DatagramPacket。其实现步骤为:

)建立发送端,接收端

)建立数据包

)调用Socket的发送、接收方法

)关闭Socket

UDP实例:



package TestTCP1;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import org.junit.Test;
//UDP编程的实现:类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。
//UDP数据报通过数据报套接字DatagramSocket发送和接收,DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。
//UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。
//(缺点是;)通信过程中系统不能保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。

public class testUDP {
	//发送端
	@Test
	public void send(){
		DatagramSocket ds = null;
		try {
			ds = new DatagramSocket();
			byte[] b = "我是发送端".getBytes();
			//创建一个数据报:每一个数据报不大于64k,且都记录着数据信息:发送端的IP、端口号,要发送到的接收端的IP、端口号。
			DatagramPacket pack = new DatagramPacket(b, 0, b.length, 
					InetAddress.getByName("127.0.0.1"), 9090);			
			ds.send(pack);//通过send()方法将数据报发送给接收端
		}catch (IOException e) {
			e.printStackTrace();
		}finally{
			//关闭DatagramSocket的对象
			if(ds != null){
				ds.close();
			}
		}		
	}
	
	@Test
	public void receive(){
		DatagramSocket ds = null;
		try {
			ds = new DatagramSocket(9090);//需要设置端口号
			byte[] b = new byte[1024];//将发送端发送的信息写入到字节数组中
			DatagramPacket pack = new DatagramPacket(b, 0, b.length);//将字节数组中的信息存入到数据报中
			
			ds.receive(pack);//接收端用receive()方法接收数据报
			String str = new String(pack.getData(), 0, b.length);//数据报转为字符串,注意参数是pack.getData()
			System.out.println(str);
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			//关闭DatagramSocket的对象
			if(ds != null){
				ds.close();
			}
		}		
	}
}



(3)URL通信编程

编程用的主要类是URL类,其过程和相关方法在注释中以给出。

URL实例:



import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
/**
 * URL:统一资源定位符
 * URL的组成结构:<传输协议>://<主机名>:<端口号>/<文件名>
 * URL中常用的方法:
	public String getProtocol(  )     获取该URL的协议名
	public String getHost(  )         获取该URL的主机名
	public String getPort(  )         获取该URL的端口号
	public String getPath(  )         获取该URL的文件路径
	public String getFile(  )         获取该URL的文件名
	public String getRef(  )          获取该URL在文件中的相对位置
	public String getQuery(   )       获取该URL的查询名
 * */
//实例:通过URL将网页内容读取到控制台。这里只考虑通信问题,编码等问题忽略。
public class testURL {
	public static void main(String[] args) {
		InputStream is1 = null;
		FileOutputStream fos = null;
		try {
			//1.创建一个URL的对象
			URL url = new URL("https://www.baidu.com/");//""中是URL的地址
			//将服务端的资源读取进来:openStream()
			InputStream is = url.openStream();
			byte[] b = new byte[1024];
			int len;
			while((len = is.read(b)) != -1){
				String str = new String(b,0,len);
				System.out.println(str);
			}
			is.close();
			//如果既有数据的输入,又有数据的输出,则考虑使用URLConnection
			URLConnection urlConn = url.openConnection();
			is1 = urlConn.getInputStream();
			fos = new FileOutputStream(new File("abc.txt"));
			byte[] b1 = new byte[20];
			int len1;
			while((len1 = is1.read(b1)) != -1){
				fos.write(b1, 0, len1);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			//关闭对应的输入输出流
			if(fos != null){
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(is1 != null){
				try {
					is1.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}