📄 tankserver.java
字号:
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import javax.swing.JApplet;
/**
* TankWar2.0坦克大战服务器
*
* @author Nighelf暗夜精灵
*
*/
public class TankServer extends JApplet {
public static int TCP_PORT = 8888; // 玩家加入游戏的TCP端口
public static int TCP_EXIT_PORT = 9999; // 预留玩家退出的TCP端口
public static int UDP_PORT = 7777; // UDP端口
private int tankId = 1000; // 分配坦克的起始ID
private int msgType = 1000;
static int totalPlayer=8;
ArrayList<Wall> walls = new ArrayList<Wall>(); // 预留服务器创建障碍物的列表
private ArrayList<Client> clients = new ArrayList<Client>(); // 保存现在玩家信息的List,在线人数的判断
DatagramSocket ds = null;
private ArrayList<Integer> removeTanksId = new ArrayList<Integer>(); //记录退出玩家的ID,重复利用ID
ServerSocket exitSer = null;
Socket s2 = null;
{
int wallCount = (int) (Math.random() * 100) + 10;
for (int i = 0; i < wallCount; i++) {
int x = (int) (Math.random() * 800 + 40);
int y = (int) (Math.random() * 600 - 40);
int style = (int) (Math.random() * 10) % 3;
// 使程序随机到3的机率小一点,类型3的障碍物是,油桶
if (style == 3) {
if ((int) (Math.random() * 10) != 0) {
style = (int) (Math.random() * 10) % 3;
}
}
walls.add(new Wall(x, y, style, null));
}
}
public TankServer() {
try {
ds = new DatagramSocket(UDP_PORT);
System.out.println("一个UDP端口" + UDP_PORT + "已启动");
exitSer = new ServerSocket(TCP_EXIT_PORT);
System.out.println("第二个TCP端口启动");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 让TCP服务器保存新玩家的信息
*/
public void start() {
UDPThread ut = new UDPThread();
Socket s = null;
ServerSocket ser = null;
try {
ser = new ServerSocket(TCP_PORT);
while (true) {
s = ser.accept();
System.out.println(s.getInetAddress() + "已连接上服务器!");
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
if (clients.size() < totalPlayer) {
int clientPort = dis.readInt();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip);
Client client = new Client(ip, clientPort);
clients.add(client);
System.out.println("得到一个客户端的IP和端口了!");
//判断空闲Id有没有,有的话分配空闲Id
if(removeTanksId.size()==0){
dos.writeInt(tankId++);
}
else{
System.out.println("加空闲Id这个的坦克!!");
int tankId = removeTanksId.get(0);
dos.writeInt(tankId);
removeTanksId.remove(0);
}
} else {
dos.writeInt(-1);
}
// 第二个TCP/IP端口,取消客户端的用户信息
new Tcp2Thread();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Tcp2Thread implements Runnable {
public Tcp2Thread() {
new Thread(this).start();
}
public void run() {
try {
while (true) {
s2 = exitSer.accept();
System.out.println(s2.getInetAddress() + "第二个TCP端口得到数据");
DataInputStream dis2 = new DataInputStream(s2
.getInputStream());
String exitip = s2.getInetAddress().getHostAddress();
int exitport = dis2.readInt();
int tankId = dis2.readInt();
for (int i = 0; i < clients.size(); i++) {
Client ec = (Client) clients.get(i);
System.out.println("exitIP:"+exitip+"IP是否相等:"+exitip.equals(ec.getIp()));
System.out.println("exitport:"+exitport+"port是否相等:"+(exitport==ec.getPort()));
System.out.println("ClientIP:"+ec.getIp()+"port:"+ec.getPort());
if (exitip.equals(ec.getIp())&&exitport==ec.getPort()) {
clients.remove(ec);
removeTanksId.add(tankId);
System.out.println("空闲ID:"+removeTanksId.size());
System.out.println(exitip + "的客户端已删除!");
System.out.println("现在的在线人数有:"+clients.size()+"人");
}
}
// 取得某个客户端的IP将其删除
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
s2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 让服务器给所有玩家转发消息
*/
class UDPThread implements Runnable {
DatagramPacket dp;
public UDPThread() {
new Thread(this).start();
}
public void send() {
try {
for (int i = 0; i < clients.size(); i++) {
Client client = (Client) clients.get(i);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(msgType);
dos.writeInt(clients.size());
for (int j = 0; j < clients.size(); j++) {
Client c = clients.get(i);
dos.writeUTF(c.ip);
dos.writeInt(c.port);
System.out.println("发送第" + i + "个用户包!!");
byte[] buf = baos.toByteArray();
dp.setSocketAddress(new InetSocketAddress(client.ip,
client.port));
dp.setPort(client.port);
ds.send(dp);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
if (ds != null) {
byte[] buf = new byte[1024];
dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
System.out.println("服务器接收到一个UDP数据包");
for (int i = 0; i < clients.size(); i++) {
Client client = (Client) clients.get(i);
dp.setSocketAddress(new InetSocketAddress(
client.ip, client.port));
dp.setPort(client.port);
ds.send(dp);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new TankServer().start();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -