基于TCP/IP协议,包含一个客户端和一个服务器端。目前只能字符聊天。
主要功能:实现多个客户端连接服务器,服务器接收到信息就会把信息广播到所有的客户端
1.Server端:包括端口设置,向所有人发信息等功能。
2.Client端:实现公聊
简洁的界面
具体的实现代码如下,代码中有相应注释,可以直接运行
Server段代码如下
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
private static ServerSocket ss;
//clients用于存储连接到server的Client
List <Client>clients=new ArrayList<Client>();
public static void main(String []args){
new ChatServer().start();
}
public void start(){
boolean started=false;
try {
ss = new ServerSocket(989);
started=true;
while(started){
//用于接收新的客户端
Socket s=ss.accept();
//启用新线程发送接收数据
Client cl=new Client(s);
clients.add(cl);
new Thread(cl).start();
//System.out.println("Server");
}
} catch (IOException e) {
try {
ss.close();
} catch (IOException e1) {
e1.printStackTrace();
}
//e.printStackTrace();
}
}
class Client implements Runnable{
private DataInputStream dis=null;
private DataOutputStream dos=null;
private Socket soc=null;
private boolean dconnected=false;
Client(Socket s){
soc=s;
}
void serSend(String st) {
//用于发送Client端传来的数据
try {
this.dos.writeUTF(st);
dos.flush();
} catch (IOException e) {
try {
dos.close();
} catch (IOException e1) {
e1.printStackTrace();
}finally{
//移除断开的Client端
clients.remove(this);
}
}
}
@Override
public void run() {
try {
dis =new DataInputStream(soc.getInputStream());
dos=new DataOutputStream(soc.getOutputStream());
dconnected=true;
while(dconnected){
String str=dis.readUTF();
//System.out.println(str);
//给每个Client端传送数据
for(int i=0;i<clients.size();i++){
Client c=clients.get(i);
c.serSend(str);
}
}
} catch (IOException e) {
System.out.println("一个客户端已关闭");
}
}
}
}
Client端代码如下,在不同的客户端运行即可
import java.awt.*;
import java.io.*;
import java.net.*;
import java.awt.event.*;
public class ChatClient {
public static void main(String[] args) {
new ChatFrame("ChatClient");
}
}
class ChatFrame extends Frame{
/**
* 实现界面,包括一个TextArea用来显示文字,一个TextField输入文字
*/
private static final long serialVersionUID = 1L;
TextField tf=new TextField();
TextArea ta=new TextArea();
String send=null;
Socket soc=null;
ChatFrame(String s){
super(s);
this.setBounds(100, 100, 500, 500);
this.add(ta,BorderLayout.NORTH);
this.add(tf,BorderLayout.SOUTH);
//加入TextField的监听,当输入完成按下回车键时发送文字
tf.addActionListener(new TextAction1());
pack();
this.setLayout(new BorderLayout());
this.setVisible(true);
//实现窗口关闭功能
this.addWindowListener(new WindowClosingAction());
connect();
//System.out.println("client");
//启动新线程实现向客户端发送数据
new Thread(new ClientRec()).start();
}
class WindowClosingAction extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
//尝试链接Server端
void connect(){
try {
//此处改为你的内网iP
soc=new Socket("192.168.1.101",989);
} catch (IOException e) {
e.printStackTrace();
}
}
//输入文本按下回车键后的反应
private class TextAction1 implements ActionListener{
//重写方法
public void actionPerformed(ActionEvent e2){
send=tf.getText();
//输入完毕后,从新设置TextField为空
tf.setText("");
//ta.setText("HuaShao:"+" "+send);
try {
DataOutputStream dos = new DataOutputStream(soc.getOutputStream());
dos.writeUTF(send);
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ClientRec implements Runnable{
public void run() {
try {
DataInputStream dis = new DataInputStream(soc.getInputStream());
while(true){
String st=dis.readUTF();
//每次显示后换到下一行
ta.setText(ta.getText()+st+'\n');
//显示文本较多时滚动条自适应
ta.setCaretPosition(ta.getText().length());
//System.out.println(st);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}