JAVA网络编程之TCP聊天室的简单实现
实现思路:服务器端接收来自不同客户端的消息,服务器端可以把接收到的消息再返回给客户端,这样就实现了消息的交互传送,这样就可以考虑服务器端用多线程实现,这样才能这样才能接收来自不同客户端的消息,并且把消息返回到客户端。而且要用容器接收一下客户端的消息。
运行方式:首先启动服务器类,再启动客户端类就可以了。
服务器容器类:
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
/*
* 服务器容器类
*/
public class ServerContext {
public ServerSocket serverSocket = null;
public List<String> list = new ArrayList<String>();//所有消息的列表
private static ServerContext serverContext = new ServerContext();
public static ServerContext instance(){
return serverContext;//懒汉模式
}
public synchronized void pushMessage(String message){
list.add(message);
}
}
服务器类:
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
/*
* 聊天室的服务器端
*/
public class TcpServer {
public static void main(String[] args) {
System.out.println("聊天室服务器启动.......");
try {
ServerContext.instance().serverSocket = new ServerSocket(9090);
//初始化线程,有几个线程就可以创建几个客户端
for(int i=0;i<5;i++){
new TcpServerThread().start();
}
while(true){//死循环让服务器端一直运行
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(ServerContext.instance().serverSocket!=null){
try {
ServerContext.instance().serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
服务器线程具体类:
import java.io.InputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import org.omg.PortableInterceptor.DISCARDING;
import java.io.OutputStream;
/*
* 聊天室的服务器端用多线程实现,这样才能接收来自不同客户端的消息,并且把消息返回到客户端
*/
public class TcpServerThread extends Thread{
@Override
public void run() {
DataInputStream did = null;
DataOutputStream dos = null;
while(true){
try {
this.sleep(2000);
Socket accept = ServerContext.instance().serverSocket.accept();
did = new DataInputStream(accept.getInputStream());
dos = new DataOutputStream(accept.getOutputStream());
if(did != null){
String string = did.readUTF();//接收收到客户端的聊天消息后,会写入ArrayList集合当中去
System.out.println("接受服务器消息:"+string);
ServerContext.instance().pushMessage(string);
//响应消息
if(ServerContext.instance().list.size()>0){
for (String message:ServerContext.instance().list) {
dos.write(message.getBytes());//再把ArayList集合中的聊天记录返回客户端
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(did!=null){
try {
did.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(dos!=null){
try {
dos.flush();
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
客户端类:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import org.omg.Messaging.SyncScopeHelper;
/*
* 聊天室的客户端
*/
public class TcpClient {
public static void main(String[] args) {
Socket socket = null;
DataInputStream dis = null;
DataOutputStream dos = null;
try {
Scanner scanner = new Scanner(System.in);
//BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));//两种从键盘输入1内容方式
System.out.println("请输入昵称:");
//String name = bufferedReader.readLine();
String name = scanner.next();
while(true){
socket = new Socket(InetAddress.getLocalHost(), 9090);
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
System.out.println("请输入要发送的消息:");
// String message = bufferedReader.readLine();
String message = scanner.next();
dos.writeUTF(name+":"+message);
int length = 0;
byte[] bs = new byte[1024];
System.out.println("*******聊天室内容*******");
while((length = dis.read(bs))!=-1){
System.out.println(new String(bs,0,length));//打印从服务器传来的消息记录
}
if(dis!=null){
try {
dis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(dos!=null){
try {
dos.flush();
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
}
}
}