黑马程序员_网络编程(UDP协议与TCP协议)

本文介绍了使用Java实现基于UDP和TCP协议的网络通讯方法。通过具体示例,包括一个简单的UDP聊天程序和一个文件上传的小程序,详细展示了如何利用Java进行网络编程。
---------- android培训java培训、java学习型技术博客,期待与您交流!----------
        在大学期间做过基于远程线程注入技术的木马,所以对套接字、UDP协议、TCP协议诸如此类网络通讯相关的内容早已熟知,不过那时候编写使用的语言是C++,如今学习java再次涉及到这部分知识,也算另一种温习吧。
        UDP和TCP这两个协议是通用协议,全球大部分网络通讯都采用这两者来实现。UDP协议是无连接、不可靠的协议。其优点在于不需要建立连接,速度快,缺点则是数据包大小限制在64K以内,且容易丢包。TCP协议是有连接、可靠的协议。它有着必须建立连接且需三次握手完成的特点。TCP协议相较于UDP协议来说更可靠,适合大数据传输,不足在于效率稍低。Socket即套接字,是网络通讯采用的方式,它起到连接两端的作用。
        先熟悉几个类。IP地址类:InetAddress,此类没有构造函数。UDP通讯的类:DatagramSocket、DatagramPacket。TCP通讯的类:Socket、ServerSocket。
        下面是以UDP协议实现的聊天程序,因为是简单演示因此两端都在一台终端上。
import java.net.*;
import java.io.*;
class Send implements Runnable{
	private DatagramSocket ds;
	public Send(DatagramSocket ds){
		this.ds = ds;
	}

	public void run(){
		try{
			BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
			String line = null;
			while((line=bufr.readLine())!=null){
				if("886".equals(line))
					break;
				byte[] buf = line.getBytes();

				DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10002);
				ds.send(dp);
			}
		}
		catch(Exception e){
			throw new RuntimeException("发送端失败");
		}
	}
}

class Rece implements Runnable{
	private DatagramSocket ds;
	public Rece(DatagramSocket ds){
		this.ds = ds;
	}

	public void run(){
		try{
			while(true){
				byte[] buf = new byte[1024];
				DatagramPacket dp = new DatagramPacket(buf,buf.length);
				ds.receive(dp);
				String ip = dp.getAddress().getHostAddress();
				String data = new String(dp.getData(),0,dp.getLength());
				System.out.println(ip+":"+data);
			}
		}
		catch(Exception e){
			throw new RuntimeException("接收端失败");
		}
	}
}

class ChatDemo{
	public static void main(String[] args) throws Exception {
		DatagramSocket sendSocket = new DatagramSocket();
		DatagramSocket receSocket = new DatagramSocket(10002);

		new Thread(new Send(sendSocket)).start();
		new Thread(new Rece(receSocket)).start();
	}
}

        上面的这个演示程序基本涉及了UDP协议下实现网络通讯所需要用到的方法,为了提高效率还是用到了IO流中的缓冲区。DatagramSocket中的send和receive方法分别用来从套接字发送和接收数据包,需要注意的是receive方法是阻塞式的。DatagramPacket中,getAddress方法用于返回IP地址,不过其返回类型是InetAddress,因此如果要单纯返回IP地址还需要再套用InetAddress的getHostAddress方法;getData方法用于返回数据缓冲区;getLength方法则是获取数据包长度。
        再来了解TCP协议下的通讯传输。鉴于其有明确的客户端和服务端,先明确这两端的执行步骤。客户端:1,创建Socket服务,并指定要连接的主机和端口。2,获取Socket输出流,将数据写到该流并发送给服务端。3,获取Socket输入流,将服务端反馈的数据获取并进行相关操作。4,关闭客户端资源。服务端:1,创建ServerSocket服务,并监听一个端口。2,通过accept获取Socket对象,没有连接则等待。3,通过Socket对象的读取流读取发送来的数据。4,获取输出流并反馈信息给客户端。5,关闭获取的客户端套接字,关闭服务端(可选)。
        通过下面这个上传文件小程序来理解。
import java.net.*;
import java.io.*;

class TextClient{
	public static void main(String[] args) throws Exception {
		Socket s = new Socket("192.168.1.254",10006);

		BufferedReader bufr = new BufferedReader(new FileReader("IPDemo.java"));

		PrintWriter out = new PrintWriter(s.getOutputStream(),true);

		String line = null;
		while((line=bufr.readLine())!=null){
			out.println(line);
		}

		s.shutdownOutput();//关闭客户端的输出流。相当于给流中加入一个结束标记-1;

		BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

		String str = bufIn.readLine();
		System.out.println(str);

		bufr.close();
		s.close();
	}
}

class TextServer{
	public static void main(String[] args) throws Exception {
		ServerSocket ss = new ServerSocket(10006);

		Socket s = ss.accept();
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"....connected");

		BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

		PrintWriter out = new PrintWriter(new FileWriter("server.txt"),true);

		String line = null;
		while((line=bufIn.readLine())!=null){
			out.println(line);
		}

		PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
		pw.println("上传成功");

		out.close();
		s.close();
		ss.close();
	}
}

        上面的代码需要说明下的是,为了方便就将上传的文件强行确定文件类型和名字存放为server.txt,在实际完成上传功能的编程中是不会这样处理的。之所以用PrintWriter替代了BufferedWriter,是看中了其既可以操作字符流也可以操作字节流并且自动刷新的特性,方便简化代码。用shutdownOutput关闭客户端输出流是为了使服务端接收到客户端传输数据结束的标识,避免出现服务端持续等待,而客户端也无法获得服务端反馈的情况。
先展示下效果 https://pan.quark.cn/s/e81b877737c1 Node.js 是一种基于 Chrome V8 引擎的 JavaScript 执行环境,它使开发者能够在服务器端执行 JavaScript 编程,显著促进了全栈开发的应用普及。 在 Node.js 的开发流程中,`node_modules` 文件夹用于存储所有依赖的模块,随着项目的进展,该文件夹可能会变得异常庞大,其中包含了众多可能已不再需要的文件和文件夹,这不仅会消耗大量的硬盘空间,还可能减慢项目的加载时间。 `ModClean 2.0` 正是为了应对这一挑战而设计的工具。 `ModClean` 是一款用于清理 `node_modules` 的软件,其核心功能是移除那些不再被使用的文件和文件夹,从而确保项目的整洁性和运行效率。 `ModClean 2.0` 是此工具的改进版本,在原有功能上增加了更多特性,从而提高了清理工作的效率和精确度。 在 `ModClean 2.0` 中,用户可以设置清理规则,例如排除特定的模块或文件类型,以防止误删重要文件。 该工具通常会保留项目所依赖的核心模块,但会移除测试、文档、示例代码等非运行时必需的部分。 通过这种方式,`ModClean` 能够协助开发者优化项目结构,减少不必要的依赖,加快项目的构建速度。 使用 `ModClean` 的步骤大致如下:1. 需要先安装 `ModClean`,在项目的根目录中执行以下命令: ``` npm install modclean -g ```2. 创建配置文件 `.modcleanrc.json` 或 `.modcleanrc.js`,设定希望清理的规则。 比如,可能需要忽略 `LICENSE` 文件或整个 `docs`...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值