从自己做的项目上截取下来的,用到了xstream工具包,我下次更新的时候贴上链接。(心血来潮写的没来得及)
服务端代码
服务端采用多线程实现,开发工具为idea。
服务端程序入口类
package domain;
import bean.ClientManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
// 程序入口类
public static ClientManager manager = new ClientManager();
public Main() {
}
//服务器程序入口方法
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(9999);
System.out.println("服务器启动");
//用死循环不断接受客户端
while(true) {
// 接收客户端的连接
Socket client = server.accept();
// 开启多线程,处理请求
(new Thread(new ClientHandler(client))).start();
}
} catch (IOException var3) {
var3.printStackTrace();
}
}
}
线程处理类(此为我本人项目的源码,具体代码可以根据自己需要修改)
package domain;
import bean.ClientManager;
import bean.Message;
import bean.MessageType;
import bean.User;
import db.DatabaseConnection;
import db.SqlOperation;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.sql.SQLException;
import java.util.Iterator;
//客户端处理类
public class ClientHandler implements Runnable {
private Socket client;
private DataOutputStream out;
private DataInputStream in;
private SqlOperation op;
private User user = new User();
//构造方法接受一个socket
public ClientHandler(Socket client) {
this.client = client;
try {
this.in = new DataInputStream(client.getInputStream());
this.out = new DataOutputStream(client.getOutputStream());
} catch (IOException var3) {
var3.printStackTrace();
}
}
//处理用户传来的消息,并返回结果
public void run() {
try {
String xml = null;
Message message = null;
// 阻塞读取客户端信息
while(true) {
while((xml = this.in.readUTF()) != null) {
message = new Message();
// 将xml转成bean实体类
message = (Message)message.fromXml(xml);
// 判断type类型,处理不同请求
switch(message.getType()) {
case 201:
this.user.setId(message.getSenderId());
this.user.setPassword(message.getContent());
this.op = new SqlOperation(DatabaseConnection.getConnection());
boolean result = this.op.doQuery(this.user);
if (result) {
Main.manager.save(message.getSenderId(), this.client);
User rightUser = this.op.findById(message.getSenderId());
System.out.println("用户个数为:"+Main.manager.getAll().size()+";账号为:"+rightUser.getId());
message.setName(rightUser.getName());
message.setSex(rightUser.getSex());
message.setNick(rightUser.getNick());
message.setSenderId(rightUser.getId());
message.setSign(rightUser.getSign());
message.setType(500);
this.reply(message);
}else {
message.setType(MessageType.MES_TYPE_LOGIN_FAILURE);
reply(message);
}
break;
case 602:
this.toOne(message);
break;
case 604:
this.user.setId(message.getSenderId());
this.user.setSign(message.getSign());
this.user.setNick(message.getNick());
System.out.println("changeInfo"+message.getSign());
if (this.op.doUpdate(this.user)) {
this.reply(new Message(800));
System.out.println("修改成功");
} else {
this.reply(new Message(801));
System.out.println("修改失败");
}
break;
case 609:
// 共享位置,将自己位置,转发所有人
this.toAll(message);
LocationManager.add(message);
for(int i = 0; i <= LocationManager.size() - 1; ++i) {
if (message.getSenderId() == LocationManager.get(i).getSenderId()) {
LocationManager.remove(i);
LocationManager.add(i, message);
} else {
// 把此用户的位置回复之前的客户端
this.reply(LocationManager.get(i));
System.out.println("回复位置");
}
}
System.out.println("位置集合中有"+LocationManager.size()+"数据");
try {
Thread.sleep(3000L);
} catch (InterruptedException var5) {
var5.printStackTrace();
}
}
}
return;
}
} catch (IOException var6) {
var6.printStackTrace();
} catch (SQLException var7) {
}
}
//返回给对应客户端
public void reply(Message message) {
try {
this.out.writeUTF(message.toXml());
this.out.flush();
System.out.println("reply--->"+message.toXml());
} catch (IOException var3) {
var3.printStackTrace();
}
}
//返回指定客户端
public void toOne(Message message) {
try {
DataOutputStream out = new DataOutputStream(Main.manager.getById(message.getReceiveId()).getOutputStream());
out.writeUTF(message.toXml());
System.out.println("toOne---->"+message.toXml());
out.flush();
} catch (IOException var3) {
var3.printStackTrace();
}
}
//返回所有在线客户端
public void toAll(Message message) {
Iterator var2 = Main.manager.getAll().iterator();
while(var2.hasNext()) {
Socket s = (Socket)var2.next();
if (s != Main.manager.getById(message.getSenderId())) {
try {
DataOutputStream out = new DataOutputStream(s.getOutputStream());
out.writeUTF(message.toXml());
System.out.println("toAll---->"+message.toXml());
out.flush();
} catch (IOException var5) {
var5.printStackTrace();
}
}
}
}
}
客户端管理类
package bean;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
//客户端管理类,全部为同步方法
public class ClientManager {
private Map<Long, Socket> users = new HashMap();
public ClientManager() {
}
//判断是否在线
public synchronized boolean isOnLine(Long id) {
Iterator var2 = this.users.keySet().iterator();
Long key;
do {
if (!var2.hasNext()) {
return false;
}
key = (Long)var2.next();
} while(!key.equals(id));
return true;
}
//保存到map中
public synchronized void save(Long id, Socket socket) {
this.users.put(id, socket);
}
//根据id取得对应Socket
public synchronized Socket getById(Long id) {
return (Socket)this.users.get(id);
}
//返回Socket集合
public synchronized Collection<Socket> getAll() {
return this.users.values();
}
// 移除map中的元素
public synchronized boolean remove(Long id){
if (isOnLine(id)){
return false;
}
{
users.remove(id);
return true;
}
}
}