Socket与DatagramSocket的网络通信

Socket与DatagramSocket的不同方式通信

一、基于TCP协议的Socket客服通信

二、基于UDP协议的DatagramSocket客服通信

由于这两种通信是基于TCP和UDP协议进行的,所有先看一下这两种协议

TCP 和 UDP
TCP协议:
  • 使用TCP协议前,须先建立TCP连接,形成传输数据通道
  • 传输前,采用“三次握手”方式,是可靠的
  • TCP协议进行通信的两个应用进程:客户端、服务端
  • 在连接中可进行大数据量的传输
  • 传输完毕,需释放已建立的连接,效率低
UDP协议:
  • 将数据、源、目的封装成数据包,不需要建立连接
  • 每个数据报的大小限制在64K内
  • 因无需连接,故是不可靠的
  • 发送数据结束时无需释放资源,速度快


一、基于TCP协议的Socket客服通信

注意点:

  • 通信的两端都要有Socket,是两台机器间通信的端点
  • 网络通信其实就是Socket间的通信
  • Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输
  • 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端

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

  1. 创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
  2. 打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用 getOutputStream()方法获得输出流,进行数据传输
  3. 按照一定的协议对 Socket  进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
  4. 关闭 Socket:断开客户端到服务器的连接,释放线路 



2)服务器程序的工作过程包含以下四个基本的步骤


  1. 调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
  2. 调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
  3. 调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。
  4. 关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。

代码实现消息互发:

注意:要先测试服务端,让其挂起,然后运行客户端

public class SocketTest {

	/*
	 * Socket
	 * 客户端 :边读(已存在的原文件)边写(到程序中) 写:是客户端的流socket.getOutputStream();
	 */
	@Test
	public void client() throws Exception, Exception{
		/*
		 * 1、客户端向服务端发送消息
		 */
		//创建一个客户端
		Socket socket = new Socket(InetAddress.getLocalHost(), 25666);
		//给服务器发送一句话
		OutputStream os = socket.getOutputStream();
		os.write("我是客户端发出的消息".getBytes());
		//告知服务器输出完了
		socket.shutdownOutput();
		
		
		/*
		 * 2、客户端接收服务器发送的消息,实现互动的效果
		 */
		InputStream is = socket.getInputStream();
		InputStreamReader isr = new InputStreamReader(is);
		BufferedReader br = new BufferedReader(isr);
		System.out.println("客户端:" + br.readLine());
		//通知服务器读完了
		socket.shutdownInput();
		//关流
		br.close();
		isr.close();
		is.close();
		os.close();
		socket.close();
	}
		/*
		 * ServerSocket
		 * 服务端 :边写(到新的文件中)边读(从程序中) 读:是服务器的流accept.getInputStream();
		 */
	@Test
	public void server() throws Exception{
		/*
		 * 1、服务端接收客户端发送的消息
		 */
		//创建一个服务端
		ServerSocket ss = new ServerSocket(25666);
		//接收客户端的请求
		Socket accept = ss.accept();
		//获取一个输入流,读取客户端发送的数据
		InputStream is = accept.getInputStream();
		InputStreamReader isr = new InputStreamReader(is);
		BufferedReader br = new BufferedReader(isr);
		System.out.println("服务器:" + br.readLine());
		accept.shutdownInput();
		
		
		/*
		 * 2、向客户端发送数据
		 */
		//获取一个输出流
		OutputStream os = accept.getOutputStream();
		os.write("我是服务端发出的消息".getBytes());
		accept.shutdownOutput();
		//关闭流
		br.close();
		isr.close();
		is.close();
		os.close();
		accept.close();
		ss.close();
		
	}
}


  • 客户端(发送消息)→服务端 (接收消息)  
  • 服务端(发送消息)→客户端(接收消息)

这两种情况我都写在同一个方法里面了,但做了很好的区分,这样更容易对比

当然不仅可以发送消息,还可以传输文件(不限文件类型)

/*
 * 客户端给服务器发送文件
 */
public class SocketTest2 {

	/*
	 * Socket
	 * 客户端: 边读(已存在的原文件)边写(到程序中) 写:是客户端的流socket.getOutputStream();
	 */
	@Test
	public void client() throws Exception, Exception{
		//创建一个客户端
		Socket socket = new Socket(InetAddress.getLocalHost(), 2566);
		//给服务器发送一句话
		OutputStream os = socket.getOutputStream();
		
		//获取一文件输入流
		FileInputStream fis = new FileInputStream(new File("F:/1.jpg"));
		byte[] b = new byte[1024];
		int len = 0;
		while((len = fis.read(b)) != -1){
			os.write(b,0,len);
		}
		socket.shutdownOutput();
		//关流
		os.close();
		socket.close();
		fis.close();
	}
	
	
	/*
	 * ServerSocket
	 * 服务端: 边写(到新的文件中)边读(从程序中) 读:是服务器的流accept.getInputStream();
	 */
	@Test
	public void server() throws Exception{
		//创建一个服务端
		ServerSocket ss = new ServerSocket(2566);
		//接收客户端的请求
		Socket accept = ss.accept();
		//获取一个输入流,读取客户端发送的数据
		InputStream is = accept.getInputStream();
		FileOutputStream fos = new FileOutputStream(new File("F:/2.jpg"));
		byte[] b = new byte[1024];
		int len = 0;
		while((len = is.read(b)) != -1){
			fos.write(b, 0, len);
		}
		accept.shutdownInput();
		is.close();
		accept.close();
		ss.close();
		fos.close();
		
	}
}

二、基于UDP协议的DatagramSocket客服通信

注意点:

  1. 类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。
  2. UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
  3. DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。
  4. UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接
public class DatagramSocketTest {

	/*
	 * 客户端
	 */
	@Test
	public void client() throws Exception{
		//第一步:创建一个客户端
		DatagramSocket socket = new DatagramSocket();
		//创建一个数据报/数据包
		/*
		 * DatagramPacket(byte[] buf, int length,
                          InetAddress address, int port)
            length : 应该是buf的长度 
		 */
		String str = "我爱爆米花";
		byte[] buf = str.getBytes();
		DatagramPacket p = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 3456);
		//第二步:发送数据
		socket.send(p);
		//第三步:关闭服务端
		socket.close();
	}
	/*
	 * 服务端
	 */
	@Test
	public void server() throws Exception{
		//第一步:创建一个服务端
		DatagramSocket ds = new DatagramSocket(3456);
		byte[] buf = new byte[1024];
		DatagramPacket p = new DatagramPacket(buf, buf.length);
		//第二步:接收数据,将数据存放到p中
		ds.receive(p);
		System.out.println(new String(buf, 0, p.getLength()));
		//第三步:关闭客户端
		ds.close();
	}
}


不管使用Socket还是DatagramSocket ,客户端都要指定IP(本机为InetAddress.getLocalHost())与端口号

而在接收端,服务端要指定监听的端口。




猜你喜欢

转载自blog.csdn.net/mxcsdn/article/details/80213379