客户端
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
/**
* <h3>untitled4</h3>
* <p></p>
*
* @author : <a href="http://antigenmhc.cn/" target=_blank>我的博客♂还蛮大的</a>
* @date : 2019-12-29 18:57
**/
public class Client extends Frame{
public static void main(String[] args) throws IOException {
//初始化界面
new Thread(new Clients("客户端1")).start();
new Thread(new Clients("客户端2")).start();
new Thread(new Clients("客户端3")).start();
new Thread(new Clients("客户端4")).start();
}
}
class Clients extends Frame implements Runnable{
//输入框
TextField textField = new TextField();
//显示框
TextArea textArea = new TextArea();
//将socket暴露出来,供给不同方法使用
Socket s = null;
PrintWriter pw = null;
InputStream is = null;
String name = null;
Clients(String name){
this.name = name;
}
@Override
public void run() {
try {
lanuchFrame();
} catch (IOException e) {
e.printStackTrace();
}
try {
while(true){
recevie();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void lanuchFrame() throws IOException {
//窗体设置
Color c = new Color(120,120,120);
Color c2 = new Color(120,120,150);
this.setBackground(c);
textArea.setBackground(c);
textField.setBackground(c2);
this.setLocation(500,400);
this.setSize(400,500);
this.setTitle(name+"的会议窗口");
//添加框框
add(textField, BorderLayout.SOUTH);
add(textArea, BorderLayout.NORTH);
pack();
//关闭窗口事件处理,使用匿名内部类
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
//窗口关闭时先断开输入输出流
disConnect();
System.exit(0);
}
});
textField.addActionListener(new Clients.TextFiledListener());
this.setVisible(true);
textArea.setText("开始轮询!\n");
//客户端
connect();
}
//链接客户端并获取输出流
private void connect(){
try {
s = new Socket("localhost",20001);
pw = new PrintWriter(s.getOutputStream(), true);
is = s.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
//断开连接和输出流
private void disConnect(){
//置为null,而不是close,因为如果直接close的同时,其余线程可能在进行read
//所以直接关掉的话,read处会报错,提示socket已关闭
//因此在关闭时可以置为null,让垃圾回收器来回收
//如果使用close的话,较为麻烦
//更好的方法是设置一个timeout
pw = null;
is = null;
s = null;
}
private void send(String str){
if(pw!=null)
pw.println(name+":"+str);
}
//接收服务端回送消息
private void recevie() throws IOException {
byte[] bytes = new byte[1024*60];
int end = is.read(bytes);
String str = null;
if(end!=-1) {
str = new String(bytes, 0, end);
textArea.setText(textArea.getText()+str+'\n'); //在显示框显示消息
}
}
//内部类监听器
private class TextFiledListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String str = textField.getText().trim(); //获得输入框字符串并去掉两端空格
//textArea.setText(str+'\n'); //在显示框显示消息
textField.setText(""); //清空输入框
//将字符串发送到服务器端
send(str);
}
}
}
服务端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* <h3>untitled4</h3>
* <p></p>
*
* @author : <a href="http://antigenmhc.cn/" target=_blank>我的博客♂还蛮大的</a>
* @date : 2019-12-29 18:57
**/
public class Server {
//用集合存储所有的客户端链接
List<Servers> clientList = new ArrayList<Servers>();
public static void main(String[] args){
new Server().start();
}
public void start(){
ServerSocket ss = null;
try {
ss = new ServerSocket(20001);
while(true){
Socket s = ss.accept();
Servers servers = new Servers(s);
clientList.add(servers);
//获得服务端集合
servers.getList(clientList);
new Thread(servers).start();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(ss != null)
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class Servers implements Runnable{
private Socket s;
List<Servers> list;
//输入流
InputStream is = null;
//输出流,并设置为自动刷新
PrintWriter pw = null;
Servers(Socket s){
this.s = s;
}
public void getList(List<Servers> list){
this.list = list;
}
@Override
public void run() {
try {
recevie();
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String str){
pw.println(str);
}
public void recevie() throws IOException {
//输入流
is = s.getInputStream();
//输出流,并设置为自动刷新
pw = new PrintWriter(s.getOutputStream(), true);
while(true){
byte[] bytes = new byte[1024*60];
int end = is.read(bytes);
String str = null;
if(end!=-1){
str = new String(bytes, 0, end);
System.out.print(str);
//循环取出client的socket,并向其对应流中写入信息
for(int i=0; i<list.size(); i++){
Servers s = list.get(i);
s.send(str);
}
}
}
}
}