在上次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!