当前位置:编程学习 > JAVA >>

QQ

package QQ;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;


import javax.swing.JTextArea;

public class Server {

int count = 0;    // 计数(记下连接客户数)
Socket sk;         // 接收来自客户端的Socket
Socket s;  // 发送时得到list中的Socket
ServerSocket ss;    // 建立服务器

Message msg;   // 接收来自客户端的封装消息类和发送的封装消息类
Message rsmsg;  // 中转客户聊天的信息的封装消息类
ServerJFrame sjf;  // 创建一个界面服务器面
JTextArea input;           // 接收来自ClientJFrame中的input,用来显示接收到得信息//JTextArea多行文本框
JTextArea output;    // 接收来自ClientJFrame中的output,用来显示发送的信息
ObjectOutputStream os;   // 发送时得到listo中的ObjectOutputStream
String deletename = new String(); // 接收来自客户端的下线消息中的姓名,以便列表中的更新删除
ListMessage lmsg = new ListMessage(); // 封装message和最新上线的客户姓名
ArrayList list = new ArrayList(); // 存储已经连接的客户的Socket
ArrayList listo = new ArrayList(); // 存储根据已经连接的客户的Socket的OutputStream构造的ObjectOutputStream
ArrayList listi = new ArrayList(); // 存储根据已经连接的客户的Socket的InputStream构造的ObjectInputStream
ArrayList listname = new ArrayList(); // 存储在线用户的姓名,以便发送给用户,让其及时更新


// 构造器
public Server() {

sjf = new ServerJFrame("服务器"); // 构造一个界面,用于显示信息
sjf.jf.setDefaultCloseOperation(sjf.jf.EXIT_ON_CLOSE); // 设定界面窗口关闭时退出程序
   
input = sjf.input;
output = sjf.output;

}

// 程序入口,启动整个Server程序
public static void main(String[] args) {
// TODO Auto-generated method stub

System.out.println("服务器登录");

Server server = new Server();
server.startServer();


}

// 开启服务器,等待客户端连接,并作出一些链接后的处理
public void startServer() {
try {
ss = new ServerSocket(9999); // 构建服务(9999)端口
msg = new Message("server", "", new Date());// 对封装消息类初始化,避免空指针
while (true) {// 循环等待连接,实现多客户连接
s = ss.accept();// 接受客户端连接
list.add(s);
listi.add(new ObjectInputStream(s.getInputStream()));
listo.add(new ObjectOutputStream(s.getOutputStream()));
ObjectInputStream fois = (ObjectInputStream) listi.get(count);
Message mname = (Message) fois.readObject();
listname.add(mname.getName());
lmsg.setMsg(msg);
lmsg.setNamenext((String) listname.get(listname.size() - 1));
SendMsg sendmsg = new SendMsg();
sendmsg.start();
ReadMsg read = new ReadMsg((ObjectInputStream) listi.get(count));
read.start();
count++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
// System.out.println("socket closed");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

// 消息发送线程,通过按钮启动发送
class SendMsg extends Thread {
Socket sk;
ObjectOutputStream os;
ListMessage lmsg = new ListMessage();

public void run() {
try {
String str = output.getText();
msg.setMsg(str);
msg.setOnlist(listname);
lmsg.setDeletename(deletename);
lmsg.setMsg(msg);
if (listname.size() != 0)
lmsg.setNamenext((String) listname
.get(listname.size() - 1));
for (int i = 0; i < list.size(); i++) {
sk = (Socket) list.get(i);
os = (ObjectOutputStream) listo.get(i);
os.writeObject(lmsg);
}//getRemoteSocketAddress()方法是socket的一个成员方法
//返回此套接字连接的端点的地址,如果未连接则返回 null
input.append("好友:" + s.getRemoteSocketAddress() + " 上线 "+new Date() + str + "\n");
output.setText("");
deletename = "";

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
// System.out.println("socket closed");
}
}
}

// 接收消息线程,处于常开状态
class ReadMsg extends Thread {
ObjectInputStream ois;

public ReadMsg(ObjectInputStream ois) {
// TODO Auto-generated constructor stub
this.ois = ois;
}

public void run() {
try {

while (true) {
lmsg = (ListMessage) ois.readObject();
if (lmsg.getMsg().getState()) {
msg = lmsg.getMsg();
msg.setOnlist(listname);
rsmsg = msg;
RSendMsg rsend = new RSendMsg();
rsend.start();//
} else {
for (int i = 0; i < listname.size(); i++) {
if (((String) listname.get(i)).equals(lmsg.getMsg().getName())) {
((InputStream) listi.get(i)).close();
((OutputStream) listo.get(i)).close();
((Socket) list.get(i)).close();
listi.remove(i);
listo.remove(i);
list.remove(i);
listname.remove(i);
count--;

}

}
}
}
} catch (IOException e) {
if (!listname.isEmpty()) {
System.out.println(listname.get(listname.size() - 1));
}
deletename = lmsg.getMsg().getName();
System.out.println(deletename);
SendMsg sendmsg = new SendMsg();
sendmsg.start();

// TODO Auto-generated catch block
// e.printStackTrace();
 System.out.println("socket closed");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

// 转发消息线程,实现客户间的聊天
class RSendMsg extends Thread {
ListMessage lmsg = new ListMessage();

public void run() {
try {
rsmsg.setOnlist(listname);
lmsg.setMsg(rsmsg);
lmsg.setNamenext((String) listname.get(listname.size() - 1));
for (int j = 0; j < listname.size(); j++) {
if (rsmsg.getCname().equals("All")) {
os = (ObjectOutputStream) listo.get(j);
os.writeObject(lmsg);
} else if (rsmsg.getCname()
.equals((String) listname.get(j))) {
os = (ObjectOutputStream) listo.get(j);
os.writeObject(lmsg);
}
}
input.append(rsmsg.toString());
output.setText("");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}


解释客户端各行
补充:Java ,  Eclipse
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,