日期:2014-05-20  浏览次数:20817 次

多个进程如何共享同一个socket
需求:为了使游戏平台和具体的游戏,比如QQ游戏大厅和地主,杀人,放火游戏进程分离,但是却有要共享同一个socket连接

C\C++实现:在windows c下编程实现可以用复制SOCKET句柄WSADuplicateSocket或共享内存的方式,但在java中不知用何种方式,或者类似的方式,我search了一下,似乎JOMP说的是共享内存,但却不知如何使用。还有真的有必要用这种方式实现游戏平台和具体的游戏分离吗,有什么更好的实现方式呢?

------解决方案--------------------
JVM据我所知,没有什么高效的进程间的通信、共享机制。
因为,不同的操作系统,其进行间的通信、共享机制都有所不同,那么,
对于跨平台,可移植性,确实是一种挑战。

一般来讲,常见的Windows和Unix系统,都是基于线程的操作系统。
也就是说,CPU的时间片会按照系统的策略分配给每一个线程,而非进程。
那么,在没有什么特殊需求的情况下,我们都会选择多线程技术来编程,而非多进程技术。

还是说点有用的吧:
我想,楼主说的问题,应该是针对服务端的程序开发。
不知道,楼主对FTP协议是否有所了解。
我指的是,控制指令与实际文件传输使用不同Socket来传输。
(这样会使程序设计简单,逻辑会比较清晰)
所以,我当然也会推荐楼主采用这种思想,来设计游戏大厅与具体游戏的关系。

实际情况下,如果游戏大厅和具体的游戏采用同一个Socket传输,那么,具体游戏的增删,会影响到通信协议的修改。
而且,客户端的编程,也会比较复杂。
Java的进程间通信,一般都是用TCP、UDP或者RMI之类的东西来实现的。所以,Socket共享,好象不太现实。
这种情况下,大厅服务器会起到类似Socket代理服务器的作用。(也就是说,如果是游戏的数据,它会转发到对应的游戏服务器上)

我推荐的程序架构是这样的:
大厅服务器与客户端采用一个Socket进行通信,各游戏采用各自的Socket进行通信(因为不同的游戏,通信数据不同,协议也不尽相同)。
大厅服务器上存放一些跟游戏服务器的相关信息(比如服务器状态,服务器IP,游戏端口之类的)
客户端的开发就比较结构清晰了。
首先,开发和大厅服务器的程序。
其次,当有新游戏要添加至大厅的时候。只要在大厅服务器上添加相关的信息就可以了。
因为,游戏的客户端程序与游戏服务器程序,本身可以相对独立的成为一个系统。

不知道我这样解释,楼主是否明白。
没有解决楼主的问题,实在不好意思。

------解决方案--------------------
先提一点:java有进程这种机制吗?就像linux一样,伪进程

------------------------
你还是没有建立在OO的基础上思考你的设计

只要你是OO的,你就能区分游戏大厅和各类游戏,因为你有大厅类,各种游戏类

然后做好分工,你的每个类负责干一些什么事情

具体到你的需求

类的生成和分配

程序运行后肯定首先有大厅类的实例,然后根据用户选择,大厅类生成对应的游戏类实例,让其运行

你完全可以大家同用一个socket

先生成socket,再生成大厅,把socket传给大厅
大厅生成socket的时候,大厅再把socket传给游戏类

你也可以各自使用自己的socket
这样socket就由类自己去创建

你还可以创建一个socketHelper
专门处理数据的收发

然后是分工
划分好那些数据应该由那些类负责处理
你所说的玩家进入、退出、逃跑等消息,这时应该是大厅类所负责处理的
如果每个游戏都需要"知晓" "这类"消息,那就由大厅根据需要去通知每个游戏类





------解决方案--------------------
另外,我不是太明白你为什么强调用进程而不能用线程?
是因为你要求分离,并把程序分成不同的文件包吧,然后大厅运行游戏的时候大厅excus()一个jar?



------解决方案--------------------
探讨
引用:
我要反问一下,设想一下,QQGame一开始运营的时候只有5个游戏,比如,双扣,杀人,放火,抢劫,偷窃;后来因为需求的原因想再加入另外四个游戏,但却不想去改动原先的代码(最多只在某个文件配置一下,告诉server我们又多了另外几个game),而在client,各个游戏和游戏大厅相互独立的,互相完全解耦,共享的是socket连接等,从扩展性角度来考虑,当然是这种方式好了,而你说的设计方式是把大厅和具体的游戏逻辑都捆绑在一起了,以后要扩展,加入游戏,就必须改动这些代码,这样的设计合理吗?


------解决方案--------------------
添加游戏也只需要把编译好的类文件down下来放在合适的目录
然后把配置文件(游戏名-游戏类文件的对应关系)修改一下
大厅读取配置需要类文件new一个实例运行就可以了

(这里应该用到java的Class.load("xxx.class").newInstands()来创建实例)
------解决方案--------------------
探讨
理解的很对,我们想把具体游戏和大厅完全独立开来,做到正真的解耦,以后新添加游戏的话,最多在大厅的配置文件里加入这个游戏的名单就行.当然server端和client端的设计又有所区别。

------解决方案--------------------
我试了一下,我说的方法完全可行

######################## 游戏大厅工程 ###########
两个文件

1.接口,既大厅和游戏间建立的规则

Java code
public interface iGame {
    public void gameLogic();
}

------解决方案--------------------
探讨
我试了一下,我说的方法完全可行

######################## 游戏大厅工程 ###########
两个文件

1.接口,既大厅和游戏间建立的规则


Java codepublic interface iGame {
public void gameLogic();
}



2.大厅程序


Java codeimport java.io.File;

public class Room {

private String[] myGames;

public Room()
{
File gameClassDir=new File("d:/games");