在上次Socket通讯 使用Socket实现简单的聊天功能 中。客户端和服务器只有一方可以发送消息,另一方则只能等待(接收消息),而且不能连续发送消息。因为发送消息和接受消息共有一条线程,需要来回的切换。这时我们就要专门为发送消息和接受消息各创建一个线程,就可以一次性发送多条消息。
步骤
1.创建一个发送消息Send类
package ThreadSocket; import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; /** * 发送消息类 */ public class Send implements Runnable{ private PrintWriter pw; private Socket socket; private String userName;//用户名(发送消息的对象) public Send() { } public Send(Socket socket, String userName) {//传入Socket和用户名 this.socket = socket; this.userName = userName; } @Override public void run() { String temp=new String(); Scanner input=new Scanner(System.in); try { pw=new PrintWriter(socket.getOutputStream(),true);//打印流 通过Socket用于发送消息 while (true){ temp=input.nextLine(); pw.println(userName+":"+temp);//将消息发送出去 if(temp.endsWith("bye"))//以bye结尾就退出 break; } } catch (IOException e) { e.printStackTrace(); }finally { if(pw!=null) pw.close(); } } }
在run()里面不能直接throws,因为run()只是实现Runnable接口,接口中的run()并没有throws。因此只能try,自己处理异常 。
2.创建一个接收消息Reception类
package ThreadSocket; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; /** * 接受消息类 */ public class Reception implements Runnable { private Socket socket; private BufferedReader br; public Reception() { } public Reception(Socket socket) { this.socket = socket; } @Override public void run() { String temp=new String(); try { br=new BufferedReader(new InputStreamReader(socket.getInputStream()));//创建缓冲流 读取消息 while (true){ temp=br.readLine(); System.out.println(temp); if(temp.endsWith("bye"))//以bye结尾就退出 break; } } catch (IOException e) { e.printStackTrace(); }finally { try { if(br!=null) br.close(); } catch (IOException e) { e.printStackTrace(); } } } }
3.创建服务器Server类,并开启发送消息和接受消息所在的线程
package ThreadSocket; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * 服务器端 */ public class Server { public static void main(String[] args) throws IOException { ServerSocket server=new ServerSocket(6666);//创建服务器并指定端口号 //开启监听 Socket socket=server.accept(); Thread send=new Thread(new Send(socket,"网管"));//创建线程 Thread reception=new Thread(new Reception(socket)); send.start();//开启线程 reception.start(); } }
4.创建客户端Client类
package ThreadSocket; import java.io.IOException; import java.net.Socket; /** * 客户端 */ public class Client { public static void main(String[] args) throws IOException { Socket socket=new Socket("localhost",6666);//ip 和 端口号 Thread send =new Thread(new Send(socket,"我")); Thread reception =new Thread(new Reception(socket)); send.start(); reception.start(); } }
5.先开启服务器端,然后开启客户端。
运行截图:
当我们开启两条线程时,发送消息和接受消息就互不干扰,这样用户体验感会好一点。
总结
在这个示例可能只是用两个类将Socket封装了一下,然后创建了两条线程。用到的知识点有:面向对象,IO流,多线程,Socket。当我们将学过的知识点组合起来使用时,好像慢慢的可以做出一些有趣的东西了。学习就是不断的总结与回顾,然后将学过的东西融会贯通的一个过程!
每日鸡汤:那有什么岁月静好,不过有人替你负重前行。
Over!