这个其实牵扯到一个通信协议的问题,各语言都有自己的socket,thread的库,直接调用即可。但是这个通信协议就需要自己来完成了。既不能太简单,太简单了,明码传输,如果别人获知了这个接口,就很容易执行一些令人讨厌的 *** 作。也不能太复杂,太复杂了等于是给自己找麻烦,所以简单的数据包编解码的工作或者用token验证的方式是需要的。通信协议起码要两种,一种是传输命令执行的协议,一种是传输文件的协议。
二、跨语言的socket通信
为什么要跨语言,主控端和代理端通信,用什么语言开发其实无所谓。但是为了给自己省事,尽可能使用服务器上已经有了的默认语言,Ambari前期采用php+puppet的方式管理集群,这不是不可以,puppet自己解决了socket通信协议和文件传输的问题,可你需要为了puppet在每台服务器上都安装ruby。我是个有点服务器和代码洁癖的人。光是为了一个puppet就装个ruby,我觉得心里特对不起服务器的资源。所以我自己写了一个python的代理端。python是不管哪个linux系统在安装的时候就都会有了。然后主控端的通信,可以用python实现,也可以用php实现,但是考虑到对于更多的使用者来说,改php可能要比改tornado简单许多,所以就没用python开发。hadoop分支版本众多,发布出去,用户要自己修改成安装适合自己的hadoop发行版,就势必要改源码,会php的明显比会python的多。php里面的model封装了所有的 *** 作,而python只是个 *** 作代理人的角色而已。
所以也延伸出一个问题,什么语言用来做这种分布式管理系统的代理端比较合适,我自己觉得,也就是python比较合适了, *** 作系统自带,原生的package功能基本够用。用java和php也可以写agent,但是你势必在各节点预先就铺设好jre或者php运行环境。这就跟为什么用python和java写mapred的人最多是一样的。没人拦着你用nodejs写mapred,也可以写,就是你得在每个节点都装v8的解释引擎,不嫌麻烦完全可以这样干。原理参看map/reduce论文,不解释。perl也是 *** 作系统原生带的,但是perl的可维护性太差了,还是算了吧。
所以这就牵扯到一个跨语言的socket问题,理论上来说,这不存在什么问题。但这是理论上的,实际开发过程中确实存在问题,比如socket长连接,通信数据包在底层的封装方式不同。我没有使用xml-rpc的原因之一就是我听说php的xmlrpc跟其他语言的xmlrpc有不同的地方,需要修改才能用,我就没有用这种办法。最早是自己定义的 *** 作协议,这时就遇到了这些问题,所以后来直接采用了thrift方式。就基本不存在跨语言的socket通信问题了。
三、代理端执行结果的获取
无论命令还是文件是否在代理端执行成功,都需要获取到执行结果返回给中央端。所以这里也涉及一个读取节点上的stdout和stderr的问题。这个总体来说不是很难,都有现成的包。当然这个时候你需要的是阻塞执行,而不能搞异步回调。
还有个问题是,我要尽可能使用python默认就带的包,而尽量不让服务器去访问internet下载第三方的包。
还有代理端最重要的一点,就是python的版本兼容性。centos5用python 24,centos6用python 26,ubuntu基本默认都是27。所以一定要最大限度的保证语言的跨版本兼容性。请打开添加删除程序——添加Windows组件,具体 *** 作为:点击开始--设置--控制面板--添加或删除程序添加/删除Windows组件(A)--Internet信息服务(iis)
然后点“确定”,插入Windows XP系统盘,点击下一步开始安装,等安装完以后,我们可以在控制面板--管理工具里面打开“Internet信息服务”开始对IIS进行配置
配置方法:
比如本机的IP地址为19216801,自己的网页放在D:\Wy目录下,网页的首页文件名为Indexhtm,现在想根据这些建立好自己的Web服务器。
对于此Web站点,我们可以用现有的“默认Web站点”来做相应的修改后,就可以轻松实现。请先在“默认Web站点”上单击右键,选“属性”,以进入名为“默认Web站点属性”设置界面。
1.修改绑定的IP地址:转到“Web站点”窗口,再在“IP地址”后的下拉菜单中选择所需用到的本机IP地址“19216801”。
2.修改主目录:转到“主目录”窗口,再在“本地路径”输入(或用“浏览”按钮选择)好自己网页所在的“D:\Wy”目录。
3.添加首页文件名:转到“文档”窗口,再按“添加”按钮,根据提示在“默认文档名”后输入自己网页的首页文件名“Indexhtm”。
4.添加虚拟目录:比如你的主目录在“D:\Wy”下,而你想输入“19216801/test”的格式就可调出“E:\All”中的网页文件,这里面的“test”就是虚拟目录。请在“默认Web站点”上单击右键,选“新建→虚拟目录”,依次在“别名”处输入“test”,在“目录”处输入“E:\All”后再按提示 *** 作即可添加成功。
5.效果的测试:打开IE浏览器,在地址栏输入“19216801”之后再按回车键,此时就能够调出你自己网页的首页,则说明设置成功!
关于IIS:
Internet Information Services(IIS,互联网信息服务),是由微软公司提供的基于运行Microsoft Windows的互联网基本服务。最初是Windows NT版本的可选包,随后内置在Windows 2000、Windows XP Professional和Windows Server 2003一起发行,但在Windows XP Home版本上并没有IIS。
要搭建一个Java多人聊天应用程序,您需要按照以下步骤进行 *** 作:
设计用户界面:设计聊天界面,包括消息列表、输入框、发送按钮等组件。
建立服务器:在云服务商或自己的服务器上建立一个服务器,用于存储和转发消息。您可以选择使用现有的聊天服务器,如Firebase Realtime Database、Google Cloud Messaging、XMPP等,也可以自己编写服务器端代码。
登录和注册:在应用中实现用户登录和注册功能,以便用户可以使用应用。
建立Socket连接:使用Socket API建立与服务器的Socket连接。您可以使用Java中的Socket或Android中的Socket类来建立连接。
发送消息:在应用中实现发送消息的功能。当用户在应用中输入一条消息并点击发送按钮时,应用将该消息发送到服务器。
接收消息:使用Socket API监听服务器发送的消息。当服务器有新消息时,应用将其接收并显示在消息列表中。
处理消息:在应用中处理接收到的消息。当应用接收到一条消息时,它需要将消息保存到本地数据库中,并更新消息列表。
实现通知:当应用在后台运行时,您需要使用通知来通知用户有新消息到达。您可以使用Android中的通知API来实现通知功能。
实现其他功能:您可能还需要实现其他功能,如消息撤回、表情符号、和文件发送等。
需要注意的是,聊天应用中的数据传输需要使用安全的方式进行,以确保用户数据不被窃取。您可以使用SSL或TLS等安全协议来保护数据传输。
同时,为了实现多人聊天,您需要在服务器端实现广播机制,将消息广播到所有连接的客户端。在Java中,您可以使用多线程来实现广播机制,每个客户端连接都在单独的线程中运行。当服务器接收到一条消息时,它将该消息发送到所有客户端连接的线程中,以便广播到所有客户端。
以上是搭建Java多人聊天应用程序的基本步骤,具体实现方式因应用需求和技术选择而异。
首先得先装javajdk,装好之后装mysql数据库,然后装apache
tomcat,然后将jsp项目放入到tomcat
webapps
目录,修改jsp项目
相关链接数据库密码,运行tomcat
即可访问,如果需要公网访问还需要将域名解析到服务器中。我最近正在itjob学这个,已经成功部署了1在电脑上安装中间件(tomcat。weblogic。。。。等)发布并启动服务。设置好端口 比如 80
2在电脑上安装花生壳软件。在软件里申请域名映射到本机。
3访问花生壳域名即可
服务器监听端口 做个无限循环 接到一个连接就创建一个通道线程,并将通道线程存储到一个list集合中
import javaioBufferedReader;import javaioIOException;
import javaioInputStreamReader;
import javaioPrintWriter;
import javanetServerSocket;
import javanetSocket;
import javatextSimpleDateFormat;
import javautilArrayList;
import javautilDate;
import javautilList;
/
4用socket通讯写出多个客户端和一个服务器端的通讯,
要求客户发送数据后能够回显相同的数据(回显功能)(实用TCP方式)。
/
public class Test4Server {
// 主入口
public static void main(String[] args) throws IOException {
scoketServer();
}
// 开启的tcp8888监听端口
public static void scoketServer() throws IOException {
ServerSocket server = new ServerSocket(8888);
while (true) {
// 未连通前线程阻塞,连通后开启一个socket通道线程后继续监听8888端口
Socket socket = serveraccept();
Systemoutprintln(socketgetInetAddress()getHostAddress()
+ "连接进入");
new SocketThread(socket)start();
}
}
}
// 一个服务器端口中监听多个客服端通道线程
class SocketThread extends Thread {
// 所有通道写入流的集合
private static List<PrintWriter> list =new ArrayList<PrintWriter>();
private BufferedReader bufferedReader;
private PrintWriter printWriter;
public SocketThread(Socket socket) throws IOException {
thisbufferedReader = new BufferedReader(new InputStreamReader(socket
getInputStream()));
thisprintWriter = new PrintWriter(socketgetOutputStream());
listadd(printWriter);
}
@Override
public void run() {
String string = null;
while (true) {
try {
// 服务器在通道中读到的信息回显给客服端
string = bufferedReaderreadLine();
Systemoutprintln("客服端信息:" + string);
for(PrintWriter printWriter:list ){
printWriterwrite("服务器回显:" + string + "\r\n");
printWriterflush();
}
} catch (IOException e) {
}
}
}
}
客服端代码 可以用在局域网中用多台来连接测试
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintWriter;
import javanetSocket;
import javautilScanner;
public class Test4Client {
public static Object obj = new Object();
// 客服端的主入口
public static void main(String[] args) throws IOException {
socketClient();
}
// 与服务器连通地址本机(127001),局域网中其他机器是(服务器在局域网中的ip地址) 端口都是8888
public static void socketClient() throws IOException {
Socket socket = new Socket("127001", 8888);
if (socketisConnected()) {
// 如果连接成功了就开启写和读的进程
new writer(socket)start();
new read(socket)start();
} else {
Systemoutprintln("服务器未开启");
}
}
}
// 写入到通道的线程
class writer extends Thread {
@SuppressWarnings("unused")
private Socket socket;
private PrintWriter printWriter;
private Scanner scanner = new Scanner(Systemin);
private String str = null;
public writer(Socket socket) throws IOException {
thissocket = socket;
thisprintWriter = new PrintWriter(socketgetOutputStream());
}
@Override
public void run() {
scanneruseDelimiter("\r\n");
while (true) {
Systemoutprint("请输入信息:");
// 产生扫描器的线程阻塞
str = scannernext();
Systemoutprintln("我说:"+str);
printWriterwrite(str + "\r\n");
printWriterflush();
try {
Threadsleep(200);
} catch (InterruptedException e) {
eprintStackTrace();
}
}
}
}
// 从通道中读取的线程
class read extends Thread {
private Socket socket;
private BufferedReader bufferedReader;
private String str = null;
public read(Socket socket) throws IOException {
thissocket = socket;
thisbufferedReader = new BufferedReader(new InputStreamReader(socket
getInputStream()));
}
@Override
public void run() {
while (true) {
try {
str = bufferedReaderreadLine();
Systemoutprintln(str);
} catch (IOException e) {
}
try {
Threadsleep(200);
} catch (InterruptedException e) {
eprintStackTrace();
}
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)