小项目实现了“电话式”聊天,即任何一方可以任何时候发送消息和接收消息。
下面先看代码,代码后面做讲解。
服务端代码:
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class Server {
private ServerSocket serverSocket;
Scanner console = new Scanner(System.in);
Socket socket;
BufferedReader br;
public Server(){
try {
System.out.println("服务器在9999端口监听...");
serverSocket = new ServerSocket(9999);
socket = serverSocket.accept();
ServerThread st = new ServerThread(socket); // 利用该Socket建立线程
Thread t = new Thread(st);
t.start(); // 启动线程
System.out.println("有客户端成功连接服务器");
// 允许不停的向客户端写消息
String mesToClient;
while (true){
mesToClient = console.nextLine(); // 从控制台读取要发送的消息
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
pw.println(mesToClient);
pw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new Server();
}
}
服务端线程代码:
import java.net.*;
import java.io.*;
import java.util.*;
/**
* 不停的读取来自客户端的消息
* */
public class ServerThread extends Thread{
private Socket s; // 服务端的socket
public ServerThread(Socket s){
System.out.println("服务端线程已成功启动");
this.s = s;
}
public Socket getS() {
return s;
}
public void setS(Socket s) {
this.s = s;
}
// 不停的读取来自客户端的消息
@Override
public void run() {
// TODO Auto-generated method stub
while (true){
try {
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(br.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
客户端代码如下:
import java.net.*;
import java.io.*;
import java.util.*;
public class Client {
private Socket socket;
private BufferedReader br;
Scanner console = new Scanner(System.in);
public Client(){
try {
socket = new Socket("127.0.0.1",9999); // 连接本机 9999 端口
ClientThread ct = new ClientThread(socket); // 为刚创建的 socket 建立一个线程
Thread t = new Thread(ct);
t.start(); // 启动线程
System.out.println("客户端已成功连接");
// 允许不停的向服务器发送消息
String mesToServer;
while (true){
mesToServer = console.nextLine(); // 从控制台读取要想客户端发送的消息
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
pw.println(mesToServer);
pw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new Client();
}
}
客户端线程代码如下:
import java.net.*;
import java.io.*;
import java.util.*;
/**
* 不停的读取来自服务端的消息
* */
public class ClientThread extends Thread{
private Socket s; // 客户端的socket
public ClientThread(Socket s){
System.out.println("客户端线程已成功启动");
this.s = s;
}
public Socket getS() {
return s;
}
public void setS(Socket s) {
this.s = s;
}
// 不停的读取来自客户端的消息
@Override
public void run() {
// TODO Auto-generated method stub
while (true){
try {
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(br.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
实现思路很简单,即客户端和服务端都需要不停的读取信息和写信息,分开来做。让Client 和 server 两个类不停的写消息,在client 和 server 中的 socket初始化后,把socket作为 clientThread 和 ServerThread的成员,让线程不停的读取消息.
因为 Client 和 ClientThread使用的是同一个Socket,而Server和ServerClient使用的也是同一个Socket,所以我们可以把Client 和 ClientThread看成一个整体,具备不停的读取消息和不停的写消息的功能,只是我们在实现的实现把读和写的功能分开了。Server和ServerClient也是同样的道理,不赘述。