⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tankserver.java

📁 基于尚学堂坦克大战的基础上开发,支持多人对战,在线聊天,坦克大战网络版.
💻 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 + -