当前位置: 首页 > news >正文

基于TCP/IP的手机聊天游戏(附带源码和解释)之服务器端类

服务器端也很简单,就是开一个ServerSocket监听Client端的连接,如果有连接,就把此连接加入到一个List中。之所以这样处理,是为了管理用户连接,比如将来你可能需要增加给特定的用户发送私人消息的功能,那么就可以从这个用户列表中寻找特定的用户进行发送。

连接建立以后利用一个单独的线程来进行通讯。

MultiPlayerServer类:

import java.io.IOException;
import java.net.ServerSocket;
import java.util.List;
import java.util.Vector;

public class MultiPlayerServer implements Server,Runnable{
private List list;

public MultiPlayerServer() {
list = new Vector();
Thread t2 = new Thread(this);
t2.start();
}

public void distributeUpdate(int type,int player_id,String content) {
ServerConnection conn;
Message msg = new Message(type,player_id,content);
for (int i = 0; i < list.size(); i++) {
conn = (ServerConnection) list.get(i);
conn.sendMessage(msg);
}
}

public synchronized void removeConnection(ServerConnection conn) {
list.remove(conn);
System.out.println("removed connection for player " + conn.getPlayerID());
System.out.println("connection list size is now " + list.size());
}

public void run() {
ServerSocket socket;

try {
socket = new ServerSocket(PORT);
System.out.println("multiplayer server listening @ " + PORT);

for (; ; ) {
synchronized (this) {
list.add(new ServerConnection(socket.accept(),this));
}
}
} catch (IOException ioe) {
System.out.println("*** MultiPlayerServer.run(): " + ioe);
}
}

}

ServerConnection类:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.*;

public class ServerConnection implements Runnable {
private MultiPlayerServer server;
private Socket socket;
private DataInputStream in;
private DataOutputStream out;
private int player_id;
private Message err;
private boolean done;

public static Hashtable userList = new Hashtable();
public static int player_count;

/**
* Create a new instance for use with game engine 'engine',
* socket 'socket', and server 'server'.
*/
public ServerConnection(Socket socket,MultiPlayerServer server) {
this.server = server;
this.socket = socket;
done = false;
Thread thread = new Thread(this);
thread.start();
}

private synchronized void handleSignup(String str) {
player_id = player_count++;
if (player_id < 0) {
System.out.println("ServerConnection.handleSignup(): engine refused player sign-up");
return;
}
userList.put(new Integer(player_id),str);
System.out.println("signed up player " + player_id);
Message msg = new Message(Message.SIGNUP_ACK,player_id,"-1");

try {
msg.archive(out);
} catch (IOException e) {
System.out.println("***: could not send msg " + err);
}
}

private void handleClientStatus(Message msg) {
server.distributeUpdate(Message.SERVER_STATUS,player_id,userList.get(new Integer(player_id))+" 说 :"+msg.getStr());
}

public int getPlayerID() {
return player_id;
}

/**
* Send a message to the client connected to this instance
*/
public synchronized void sendMessage(Message msg) {
try {
msg.archive(out);
} catch (IOException e) {
System.out.println("***: could not send msg " + msg);
}
}

/**
* main loop
*/
public void run() {
Message msg;

try {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());

while (!done) {
msg = Message.createFromStream(in);
switch (msg.getType()) {
case Message.SIGNUP:
System.out.println("Server is handling : SIGNUP");
handleSignup(msg.getStr());
System.out.println("Server After : SIGNUP");
break;
case Message.CLIENT_STATUS:
System.out.println("Server receive : CIENT_STATUS");
handleClientStatus(msg);
break;
case Message.SIGNOFF:
break;
default:
break;
}
}

in.close();
out.close();
socket.close();
} catch (Exception ioe) {
System.out.println("*** ServerConnection.run(): " + ioe);
server.removeConnection(this);
}
server.removeConnection(this);
System.out.println("player " + player_id + " disconnected.");
}

}

相关文章:

  • java显示图片缩略图_java中生成图片的缩略图
  • 基于TCP/IP的手机聊天游戏(附带源码和解释)之客户端类
  • 在DataGrid等控件中添加自动编号的列
  • java 循环队列实现_Java实现循环队列
  • 长期用电脑人士要多吃樱桃
  • [软工]此EUP非彼EUP
  • java 加减乘除是原子操作吗_Go并发编程之传统同步—(3)原子操作
  • 毕业了
  • mysql innodb 删除_MySQL InnoDB 删除资料后释放硬盘空间
  • request变量java jsp_JSP里request变量列表
  • transition java_Transition 过渡
  • 相对最完整的软件测试工具手册
  • 上传图片并且生成可以控制大小图片清晰度的方法
  • 手机php开发环境,PHP开发环境搭建
  • 要不要把php5升级到php7,将php5升级到php7后AJAX不工作
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • AngularJS指令开发(1)——参数详解
  • JDK 6和JDK 7中的substring()方法
  • JS函数式编程 数组部分风格 ES6版
  • JS实现简单的MVC模式开发小游戏
  • js中forEach回调同异步问题
  • Kibana配置logstash,报表一体化
  • php ci框架整合银盛支付
  • PHP那些事儿
  • Quartz初级教程
  • spring cloud gateway 源码解析(4)跨域问题处理
  • SQLServer之索引简介
  • TypeScript迭代器
  • vue 个人积累(使用工具,组件)
  • 关于使用markdown的方法(引自CSDN教程)
  • 聚类分析——Kmeans
  • 开发基于以太坊智能合约的DApp
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 容器服务kubernetes弹性伸缩高级用法
  • 数据可视化之 Sankey 桑基图的实现
  • 2017年360最后一道编程题
  • const的用法,特别是用在函数前面与后面的区别
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • # Panda3d 碰撞检测系统介绍
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #WEB前端(HTML属性)
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (C语言)字符分类函数
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (动态规划)5. 最长回文子串 java解决
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .net core 连接数据库,通过数据库生成Modell
  • .NET MVC第五章、模型绑定获取表单数据