Socket群聊

package TestSocket01;


import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class MyForm extends JFrame{

private static final long serialVersionUID = 1L;
// private JButton jbSent = new JButton("发送");
private JLabel jlabelName = new JLabel("用户昵称:");
private JTextArea jtaName = new JTextArea("");
private JTextArea jtaShow = new JTextArea("");
private JTextArea jtaWrite = new JTextArea("");

public MyForm() {
//测试!
}

public MyForm(String str) {
super(str);
}

public void mShow() {
this.setVisible(true);
}

public void mClose() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public void mform() {

this.setLayout(null);
this.setBounds(300, 300, 500, 500);
//this.getContentPane().setBackground(new Color(200, 90, 30)); nothing
this.getContentPane().setBackground(Color.gray);

jlabelName.setBounds(10, 10, 900, 25);
jtaName.setBounds(100, 10, 200, 25);

// jbSent.setBounds(400, 400, 80, 30);
JScrollPane jspShow = new JScrollPane(jtaShow);
JScrollPane jspWrite = new JScrollPane(jtaWrite);

jspShow.setBounds(30, 40, 350, 350);
jtaShow.setLineWrap(true);
jtaShow.setEditable(false);
jtaShow.setCaretPosition(jtaShow.getDocument().getLength());

jspWrite.setBounds(30, 400, 330, 35);
jtaWrite.setLineWrap(true);
jtaWrite.setCaretPosition(jtaWrite.getDocument().getLength());

this.add(jlabelName);
this.add(jtaName);
this.add(jspShow);
this.add(jspWrite);
}

public String getName() {
return jtaName.getText();
}

public void setMessage(String message) {
jtaShow.append(message+"/n"); //添加信息并换行。
//jtaShow.setWrapStyleWord(true);
}

public String getMessage() {
if (!(jtaWrite.getText()).equals("")) { //如果写的东西不为空
if (!(jtaName.getText()).equals("")) { //判断是谁写的信息
return (jtaName.getText() + ": " + jtaWrite.getText());
} else {
return ("ClientX: " + jtaWrite.getText()); //无名氏默认是ClientX
}
} else { //什么都没写
return "";
}
}

public void clearWrite() { //清空所写的东西。
jtaWrite.setText("");
}

public static void main(String[] args) {
MyForm mf = new MyForm(); //测试用的而已。
mf.mform();
mf.mShow();
mf.mClose();

}
}

===========================客户端 socketClient.java===================================

package TestSocket01;


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.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;

public class socketClient implements Runnable {
private Socket s;
private DataInputStream dis;
private DataOutputStream dos;
private boolean flag = true; //标志 如果多个客户端则会出错。

private MyForm mf = new MyForm("通讯客户端"); //新建了一个客户端的界面。
private JButton jbSent = null;

private boolean serverClose = false;// 标识服务器端是否关闭,true为关闭,false为没关闭

public socketClient() {
mf.mform();
mf.mShow();
mf.mClose();

try {
jbSent = new JButton("发送");
jbSent.setBounds(400, 400, 80, 30); //设置按钮的大小
mf.add(jbSent); //添加到JFrame中
s = new Socket("222.17.110.117", 55551); //此处新建了一个Socket,并连接服务器。通信从此位置开始。
jbSent.addActionListener(new ActionListener() { //“发送”按钮监听
public void actionPerformed(ActionEvent e) { //监听按钮的方法。必须实现的。
try {
if(!serverClose){ // 第一次执行时,默认是开着的。之后,如果服务器开着,即没有关闭,则发送下面内容
String message = mf.getMessage(); //取得某人写的某些内容
if (!message.equals("")) {
System.out.println(message); //后台打印测试而已!
dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(message); //把message通过s输出去
mf.clearWrite(); //此处只有发送按钮在监听,故发送之后,内容理应删掉。
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
mf.addWindowListener(new WindowAdapter() { // 监听客户端是否关闭,如果关闭,则向服务器发送一个“exit”字符串
public void windowClosing(WindowEvent e) {
try {
if (serverClose) { //serverClose 的值一直都是false。
//此处永远不会被执行。
} else { //因为监听到了窗口被关闭了。
dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF("exit"); //既然关闭了,就发送个信号给服务器。删除该客户端。
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
});

new Thread(this).start(); //打开一个线程,即执行本类的run()函数。
} catch (UnknownHostException e) {
e.printStackTrace();//打印出错信息而已,别无他意。
} catch (IOException e) {
serverClose=true;
mf.setMessage("服务器不存在或未打开!");
}
}

public void run() {
while (flag) {
try {
dis = new DataInputStream(s.getInputStream());
mf.setMessage(dis.readUTF());
} catch (IOException e) {
serverClose = true; //服务器可能在有客户端存在的时候关闭,此时,客户端输入流会出错,刚执行此处
mf.setMessage("服务器关闭了!");
flag=false;//跳出循环
}
}
}

public static void main(String[] agrs) {
new socketClient(); //先开服务器,再开客户端。代码入口处。
}
}

==================================服务器 socketServer.java==============================

package TestSocket01;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
//服务器端
public class socketServer {
private ServerSocket ss;
private Socket s;
private DataInputStream dis;
private DataOutputStream dos;
private static Vector<Client> v = new Vector<Client>();
private Client client;


public socketServer() {
try {
ss = new ServerSocket(55551);
System.out.println("服务器已经启动!"); //后台提示
while (true) {
try {
s = ss.accept(); //一直在等待连接
System.out.println(s);
dis = new DataInputStream(s.getInputStream()); //初始化Socket的两个流。
dos = new DataOutputStream(s.getOutputStream());

System.out.println(v.size()); //打印此时登陆客户端的个数。
client = new Client(v.size(),dos, dis); //说明一个客户端连接上了,给个线程。只能定义一次。。。
v.addElement(client); //往向量里面添加一个客户端。
client.start(); //启动一个线程
System.out.println(getVectorSize());//打印此时登陆客户端的个数。
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
System.out.println("服务器启动失败!");
}
}

public static int getVectorSize() {
return v.size();
}

public static Vector<Client> getVector() {
return v;
}

public static void main(String[] args) {
new socketServer();
}
}
//每个客户端线程连接过去,则建立一个该对象
class Client extends Thread {
int id;
DataOutputStream dos;
DataInputStream dis;

public Client( int id,DataOutputStream dos, DataInputStream dis) {
this.id=id;
this.dis = dis;
this.dos = dos;
}

public void run() { //启动时便执行该段代码!
boolean flag = true; //只是一个标志
int m;
while (flag) {
try {
String message = dis.readUTF(); //输入进来的流,简称输入流,拿到客户端的信息。
System.out.println(message); //后台打印出来
if (message.equals("exit")) {//如果接收到"exit"字符串,说明运行该线程的客户端断开了连接,则需退出该循环,退出线程
flag = false; //退出循环
socketServer.getVector().remove(this); //当客户端关闭时,从Vector里除去本对象
} else {
m = socketServer.getVectorSize(); //返回共有多少个客户端目前。
for (int i = 0; i < m; i++) { //给每个客户端发送同样的信息。
socketServer.getVector().get(i).dos.writeUTF(message); //输出信息给每个客户端。
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

你可能感兴趣的:(java,.net,swing,socket,dos)