一个Java初学者写出来的界面简陋,功能及其简单的小白版聊天室,接下来会花一点时间去完善它
1.构思:构建两个main方法,一个为服务端,一个为客户端,客户端向服务端发送消息,服务端创建集合,向集合中的所有客户端发送信息。
2,涉及知识点:流,swing,网络通信,多线程,异常等的入门简单使用
3,代码如下
客户端:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.rmi.UnexpectedException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Calendar;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ChatClient extends JFrame {
Socket s;
int x=(int)(Math.random()*100);//给每一个端口随机指定一个端口值
DataOutputStream dos=null;
DataInputStream dis=null;
private boolean bconnect=false;
JTextField tfTxt=new JTextField();
JTextArea taContent=new JTextArea();
public static void main(String[] args) {
new ChatClient().launchFrame();
}
public void launchFrame() {
this.setLocation(400,300);
this.setSize(400,400);
this.add(tfTxt, BorderLayout.SOUTH);
this.add(taContent, BorderLayout.NORTH);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent arg0){
disconnect();//确定关闭后断开连接
System.exit(0);
}
});
tfTxt.addActionListener(new TFListener());//添加动作监听
this.setVisible(true);
connect();//与服务端进行连接
new Thread(new RecvThread()).start();//开启多线程
}
public void connect() {
try {
s=new Socket("127.0.0.1",8888);
dos=new DataOutputStream(s.getOutputStream());//获取s端的输出流
dis=new DataInputStream(s.getInputStream());//获取s端的输入流
bconnect=true;
}catch(UnexpectedException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
}
public void disconnect() {
try {
dos.close();
s.close();
}catch(IOException e) {
e.printStackTrace();
}
}
private class TFListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
Calendar cal=Calendar.getInstance();
String str="Client "+x+" "+LocalDate.now().toString()+LocalTime.now().toString()+
":\n"+tfTxt.getText().trim();//trim的作用是去除两边空格
//taContent.setText(str);
tfTxt.setText("");//将发送后的tfTxt置空
try {
DataOutputStream dos=new DataOutputStream(s.getOutputStream());
dos.writeUTF(str);//dos作为输出流存储输出到服务端的内容
dos.flush();
//dos.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
private class RecvThread implements Runnable{
public void run() {
try {
while(bconnect) {
String str = dis.readUTF();
System.out.println(str);
taContent.setText(taContent.getText()+str+"\n");
}}
catch(EOFException e) {//异常的捕捉顺序
System.out.println("退出1");
}
catch(SocketException e) {
System.out.println("退出2");
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
服务端:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
public class ChatSerive {
boolean started=false;
ServerSocket ss=null;
List<Client> clients=new ArrayList<>();
public static void main(String[] args) {
new ChatSerive().start();
}
public void start() {
try {
ss=new ServerSocket(8888);
}
catch(BindException e2) {
System.out.println("端口使用中。。");
System.exit(0);
}
catch(IOException e) {
e.printStackTrace();
}
try {
started=true;
while(started) {
Socket s=ss.accept();
Client c=new Client(s);
new Thread(c).start();//线程启动
clients.add(c);//将线程添加到集合中
}}catch(IOException E) {
E.printStackTrace();
}
finally {
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Client implements Runnable{//创建一个内部类线程
Client c;
Socket s;
DataInputStream dis=null;
boolean bconnect=false;
DataOutputStream dos=null;
public Client(Socket s) {
this.s=s;
try {
dos=new DataOutputStream(s.getOutputStream());
dis=new DataInputStream(s.getInputStream());
bconnect=true;//判断是否成功读取输入流
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void send(String str){
try {
dos.writeUTF(str);
} catch (IOException e) {
// TODO Auto-generated catch block
clients.remove(this);
System.out.println("对方退出了");
}
}
public void run() {
try {
while(bconnect) {
String str=dis.readUTF();
for(int i=0;i<clients.size();i++) {//判断有几个客户端,向所有客户端发送信息
Client c=clients.get(i);
c.send(str);
}
//System.out.println(str);
}}catch(SocketException e) {
if(c!=null) clients.remove(this);
System.out.println("quit");
}
catch(EOFException e) {
System.out.println(1);
e.printStackTrace();
}
catch(IOException e){
System.out.println("Client closed");
}finally {
try {
if(dis!=null) dis.close();
if(dos!=null) dos.close();
if(s!=null) s.close();
}catch(IOException e1) {
e1.printStackTrace();
}
}
}
}
}
/*for(Iterator<Client>it=clients.iterator();it.hasNext();) {
Client c=it.next();
c.send(str);
}*///Iterator具有锁定功能,较慢
/*Iterator<Client>it=clients.iterator();
while(it.hasNext()) {
Client c=it.next();
c.send(str);
}*/
集合的遍历输出的另外两种方法