实现过程:
包括四个类:1,ChatClient:输入用户名,启动客户端子线程。2,ClientThread:根据用户名与服务端连接,接收服务端转发的消息并显示。
3,ChatServer:监听客户端请求,交给服务端子线程处理。4,ServerThread:处理客户端输入/输出和消息转发任务,在构造函数中在第一次建立连接时读取客户端发送的用户名并将其添加到客户端列表
package com.test.example;
import java.io.*;
import java.net.*;
public class ChatClient {
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
ClientThread client = new ClientThread(args[0]) ;
client.start() ;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;
//读取键盘输入
String readline ;
while((readline = br.readLine()) != null){
if(readline.equals("bye")){
client.close() ;
System.exit(0) ;
}
client.send(readline) ;
}
}catch(IOException e){
e.printStackTrace() ;
}
}
}
package com.test.example;
import java.io.*;
import java.net.*;
public class ClientThread extends Thread {
Socket socket ;
BufferedReader br ;
PrintWriter pw ;
//启动客户端
public ClientThread(String username){
try{
//连接服务端
socket = new Socket("localhost", 12345) ;
br = new BufferedReader(new InputStreamReader(socket.getInputStream())) ;
pw = new PrintWriter(socket.getOutputStream()) ;
//发送用户名
pw.println(username) ;
pw.flush() ;
}catch(IOException e){
e.printStackTrace() ;
}
}
//读取从服务端转发来的消息
public void run(){
try{
String readLine ;
while((readLine = br.readLine()) != null){
System.out.println("消息来自: " + readLine) ;
}
}catch(IOException e){
e.printStackTrace() ;
}
}
//发送消息
public void send(String message){
pw.println(message) ;
pw.flush() ;
}
//关闭客户端
public void close(){
try{
br.close() ;
pw.close() ;
socket.close() ;
}catch(IOException e){
e.printStackTrace() ;
}
}
}
package com.test.example;
import java.io.*;
import java.util.*;
import java.net.*;
public class ChatServer {
public static void main(String[] args) {
// TODO Auto-generated method stub
ServerSocket server = null ;
try{
server = new ServerSocket(12345) ;
System.out.println("服务器启动:" + server.getInetAddress().getHostAddress() + ":" + server.getLocalPort()) ;
//客户端列表
Hashtable<String, ServerThread> clienList = new Hashtable<String, ServerThread>() ;
//监听,处理
while(true){
Socket socket = server.accept() ;
new ServerThread(socket,clienList).start() ;
}
}catch(IOException e){
e.printStackTrace() ;
}finally{
try{
server.close() ;
}catch(IOException e){
e.printStackTrace() ;
}
}
}
}
package com.test.example;
import java.io.*;
import java.util.*;
import java.net.*;
public class ServerThread extends Thread {
Socket socket ;
BufferedReader br ;
PrintWriter pw ;
Hashtable<String, ServerThread> clientlist ; //客户端列表
String username ; //用户名
public ServerThread(Socket socket, Hashtable<String, ServerThread> clientlist){
this.socket = socket ;
this.clientlist = clientlist ;
try{
br = new BufferedReader(new InputStreamReader(socket.getInputStream())) ;
pw = new PrintWriter(socket.getOutputStream()) ;
//读取用户名
this.username = br.readLine() ;
clientlist.put(username, this) ;
//显示连接信息
System.out.println(username + "连接:" + socket.getInetAddress().getHostAddress() + ":" + socket.getLocalPort()) ;
}catch(IOException e){
e.printStackTrace() ;
}
}
public void run(){
try{
//处理客户端输入
String line ;
while((line = br.readLine()) != null){
//用户输入信息
System.out.println(username + "发给 " + line) ;
System.out.println() ;
if(line.equals("bye"))
break ;
else{
//转发消息
String []arr = line.split(":") ;
if(arr.length == 2){
if(clientlist.containsKey(arr[0])){
clientlist.get(arr[0]).send(username + ":" + arr[1]) ;
}
}
}
}
br.close() ;
pw.close() ;
socket.close() ;
}catch(IOException e){
e.printStackTrace() ;
}
}
public void send(String message){
System.out.println("发给" + username + " " + message) ;
pw.println(message) ;
pw.flush() ;
}
}