java实现文本转换器

本文档详细介绍了如何使用Java实现一个TCP连接的文本转换器。客户端通过键盘输入文本,服务端接收到文本后将其转化为大写并回传。当输入'over'时,双方关闭连接。分析了客户端和服务端的数据传输过程,强调了缓冲区和换行符的重要性,并提供了四段代码示例,分别展示了不同线程处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求和分析

  用java实现文本转换器
  这是一个TCP连接。客户端将文本发送到服务端,服务端会将文本转换成大写形式,并返回给客户端。当客户端发送“over”的时候,就关闭客户端和服务端。
  分析:
  1、客户端
  客户端从键盘录入数据,然后发送到服务端。这个过程中,源是键盘录入,目的是网络输出流,并且都是字符,因此可以使用字符流。为了提高效率,加入缓冲区技术。如果键盘录入的是“over”,那么会发送“over”,并且关闭资源。
  客户端从网络输入流中接收服务端发来的大写形式,这个过程中,源是网络输入流,目的是控制台,直接输出即可。
  2、服务端
  服务端从网络输入流中获取数据,这个过程中,源是网络输入流,使用加入缓冲区技术的字符流。对接收的文本进行处理,如果是“over”,那么直接关闭资源,如果不是,那么对其进行大写转换,然后发送给客户端,这个过程中,目的是网络输出流。
  3、注意
  在输出流中,如果使用BufferedWriter对象,那么注意写入数据之后一定要flush,否则数据只是写到了缓冲区,并没有写到真正的目的。因为对方读取都是调用readLine(),这是阻塞式方法,必须有换行符才可以,否则一直阻塞,因此写的时候,需要加入换行符。
  当然也可以使用PrintWriter,调用println()能够将数据直接输出到指定流中,并且自动换行。PrintWriter(OutputStream/Writer out, true)中的true可以使得流能够有效的自动刷新,该类的构造函数,既可以接收字节流,也可以接收字符流,因此更为简便。
  当客户端关闭连接的时候,会向socket流中写入-1,这样服务端在读到-1的时候,就知道客户端关闭了连接,就会关闭服务器的socket服务,通信结束。代码1-3都是使用了客户端和服务端两个线程,代码4将客户端拆成发送线程和接收线程,更符合实际通信过程。

代码1:

/* 
使用字节流进行读写操作。
*/
import java.io.*;
import java.net.*;

//客户端
class TCPClient{
	public static void main(String[] args)throws Exception{
		//创建socket服务,并建立到服务器的连接
		Socket s = new Socket("192.168.254.136", 8000);

		//键盘录入需要转换的文本
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

		//网络输出流,将键盘录入的数据输出到输出流中,发送到服务端
		OutputStream out = s.getOutputStream();
		InputStream in = s.getInputStream();

		String line = null;
		while((line = bufr.readLine()) != null){
			out.write(line.getBytes());
			if("over".equals(line)){
				break;
			}

			//循环接收数据
			byte[] buf = new byte[1024];
			int len = in.read(buf);
			String data = new String(buf, 0, len);

			System.out.println("文本转换后:"+data);
		}

		//关闭资源
		bufr.close();
		s.close();
	}
}

//服务端
class TCPServer{
	public static void main(String[] args)throws Exception{
		//创建socket服务,监听指定端口
		ServerSocket ss = new ServerSocket(8000);

		//阻塞等待客户端的连接请求
		Socket cs = ss.accept();

		//通过客户端的socket获取输入流
		InputStream in = cs.getInputStream();
		//通过客户端的sokcet获取输出流
		OutputStream out = cs.getOutputStream();

		//循环接收和发送数据
		while(true){
			byte[] buf = new byte[1024];
			int len = in.read(buf);

			if(len > 0){
				String data = new String(buf, 0, len);

				//如果是over,就关闭资源
				if("over".equals(data)){
					break;
				}
				System.out.println("客户端发来的文本是:"+data);

				out.write(data.toUpperCase().getBytes());
			}
			else{
				break;
			}
		}

		//关闭资源
		cs.close();
		ss.close();
	}
}

代码2:

/*
使用加入了缓冲技术的字符流,注意flush和添加换行符
*/
import java.io.*;
import java.net.*;

//客户端
class TCPClient{
	public static void main(String[] args)throws Exception{
		//创建socket服务,并建立到服务器的连接
		Socket s = new Socket("192.168.254.136", 8000);

		//键盘录入需要转换的文本
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		//通过socket流获取输出流,将文本数据发送到服务端
		BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		//通过socket流获取输入流,获取服务端发来的数据
		BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));

		String line = null;
		while((line = bufr.readLine()) != null){
			//将文本数据发送到服务端
			bufout.write(line);
			bufout.newLine();//换行符表示一个完整的独立文本数据
			bufout.flush();

			//如果发送的的over,那么退出并关闭资源
			if("over".equals(line)){
				break;
			}

			//通过网络输入流获取转换结果
			String data = bufin.readLine();

			System.out.println("转换后的结果是:"+data);
		}

		//关闭资源
		s.close();
		bufr.close();
		bufin.close();
		bufout.close();
	}
}

//服务端
class TCPServer{
	public static void main(String[] args)throws Exception{
		//创建socket服务,监听指定端口
		ServerSocket ss = new ServerSocket(8000);

		//阻塞等待客户端的连接请求
		Socket cs = ss.accept();

		//通过客户端的socket获取网络输入流
		BufferedReader bufin = new BufferedReader(new InputStreamReader(cs.getInputStream()));
		//通过客户端的socket获取网络输出流
		BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(cs.getOutputStream()));

		String line = null;
		while((line = bufin.readLine()) != null){
			//当发送的是over,那么退出并关闭资源
			if("over".equals(line)){
				break;
			}
			System.out.println("客户端发来的文本数据是:"+line);

			//将转换后的数据发送给客户端
			bufout.write(line.toUpperCase());
			bufout.newLine();//换行符使数据成为独立完整的文本
			bufout.flush();//将数据写入目的中
		}

		//关闭资源
		cs.close();
		ss.close();
		bufin.close();
		bufout.close();		
	}
}

代码3:

/*
使用打印字符流,可以避免flush和添加换行符的操作,实现更简便。
*/
import java.io.*;
import java.net.*;

//客户端
class TCPClient{
	public static void main(String[] args)throws Exception{
		//创建socket服务,并建立到服务器的连接
		Socket s = new Socket("192.168.254.136", 8000);

		//键盘录入需要转换的文本
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		//通过socket流获取输出流,将文本数据发送到服务端
		PrintWriter pw = new PrintWriter(s.getOutputStream(), true);

		//通过socket流获取输入流,获取服务端发来的数据
		BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));

		String line = null;
		while((line = bufr.readLine()) != null){
			//将文本数据发送到服务端
			pw.println(line);//连同数据和换行符一并写到目的中

			//如果发送的的over,那么退出并关闭资源
			if("over".equals(line)){
				break;
			}

			//通过网络输入流获取转换结果
			String data = bufin.readLine();

			System.out.println("转换后的结果是:"+data);
		}

		//关闭资源
		s.close();
		bufr.close();
		bufin.close();
		pw.close();
	}
}

//服务端
class TCPServer{
	public static void main(String[] args)throws Exception{
		//创建socket服务,监听指定端口
		ServerSocket ss = new ServerSocket(8000);

		//阻塞等待客户端的连接请求
		Socket cs = ss.accept();

		//通过客户端的socket获取网络输入流
		BufferedReader bufin = new BufferedReader(new InputStreamReader(cs.getInputStream()));
		//通过客户端的socket获取网络输出流
		PrintWriter pw = new PrintWriter(cs.getOutputStream(), true);

		String line = null;
		while((line = bufin.readLine()) != null){
			//当发送的是over,那么退出并关闭资源
			if("over".equals(line)){
				break;
			}
			System.out.println("客户端发来的文本数据是:"+line);

			//将转换后的数据发送给客户端
			pw.println(line.toUpperCase());
		}

		//关闭资源
		cs.close();
		ss.close();
		bufin.close();
		pw.close();
	}
}

代码4:

/*
客户端
1、发送线程
键盘录入发送数据,直到输入over的时候,就不能发送,退出线程并关闭资源
2、接收线程
一直开启,但是当发送端发送over的时候,会关闭客户端套接字,使得接收线程也无法运行
服务端
服务端也是有发送端和接收端,接收端接收到数据然后处理,通过发送端发送出去,所以发送端和接收端共用这个数据资源,为了简化操作,将发送和接收放在一个线程中
*/
import java.io.*;
import java.net.*;

//客户端的发送线程
class TCPClientSend implements Runnable{
	private Socket s;

	//构造函数
	TCPClientSend(Socket s){
		this.s = s;
	}

	//复写run(),线程启动即执行此函数
	public void run(){
		try{
			//键盘录入
			BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
			//获取socket流中的输出流,并转成字符流,加入缓冲技术
			BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

			String line = null;
			while((line = bufr.readLine()) != null){
				//将键盘录入的数据发送到服务端
				bufout.write(line);
				bufout.newLine();
				bufout.flush();

				//如果发送的是over,那么退出线程并关闭资源
				if("over".equals(line)){
					break;
				}
			}
			//关闭资源
			bufr.close();
			bufout.close();
			s.close();
		}
		catch(Exception e){
			throw new RuntimeException("send exception");
		}
	}
}

//客户端的接收线程
class TCPClientRecv implements Runnable{
	private Socket s;

	//构造函数
	TCPClientRecv(Socket s){
		this.s = s;
	}

	//复写run(),线程开启就执行该函数
	public void run(){
		try{
			//一直在接收,所以用循环
			while(true){
				//获取socket流的输入流,获取数据
				BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));

				String line = null;
				while((line = bufin.readLine()) != null){
					System.out.println("转换后的内容是:"+line);
				}
			}
		}
		catch(Exception e){
			throw new RuntimeException("receive exception");
		}
	}
}

//客户端
class Tcp_Client{
	public static void main(String[] args)throws Exception{
		//创建socket服务,并和服务端建立连接
		Socket s = new Socket(InetAddress.getLocalHost(), 8000);

		//开启发送和接收线程
		new Thread(new TCPClientSend(s)).start();
		new Thread(new TCPClientRecv(s)).start();
	}
}

//服务端
class Tcp_Server{
	public static void main(String[] args)throws Exception{
		//创建socket服务,监听指定端口
		ServerSocket ss = new ServerSocket(8000);

		//阻塞等待客户端的连接请求
		Socket cs = ss.accept();

		//通过客户端的套接字获取网络输入流,获取客户端发来的信息
		BufferedReader bufin = new BufferedReader(new InputStreamReader(cs.getInputStream()));
		//通过客户端的套接字获取网络输出流,将转换后的大写形式发送给客户端
		PrintWriter out = new PrintWriter(cs.getOutputStream(), true);

		String line = null;
		while((line = bufin.readLine()) != null){
			//如果收到了over,那么退出并关闭资源
			if("over".equals(line)){
				break;
			}

			System.out.println("客户端发来数据:"+line);

			//将转换后的大写形式发送给客户端
			out.println(line.toUpperCase());//直接将大写形式写到输出流中并且换行
		}

		//关闭资源
		bufin.close();
		out.close();
		cs.close();
		ss.close();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值