如何实现两个java程序之间的相互通讯,不想用Socket

如何实现两个java程序之间的相互通讯,不想用Socket,第1张

不用也可以。
通讯就是对数据进行交换,数据可以保存在硬盘上。
设置硬盘上的文件为数据沟通的桥梁就可以实现不用Socket进行两个程序间的通讯了(同一主机上)。
更具体一点的实现可以是:
两个程序间要进行通讯(a、b),设置两个文件夹(d://a、d://b),程序a将要发送的消息通过文件的方式放在文件夹a中,b程序的消息放b文件夹,每一个消息都是一个单独的文件,文件名用当前时间命名。
a程序中监控b文件夹中的文件数量,每当文件数量增加便读取新文件所包涵的信息,当文件夹中的文件数量超过10就清空一次文件,防止无用数据一直占着存储空间,b程序和a程序基本一致,只不过监控的文件夹换成了文件夹a。
如果真有这方面的需求,需要用这种方式实现,先做个框架会方便很多。

首先ping一下,看看两个电脑能ping的通不?
如果ping不通,看看防火墙是否设置好了
如果能ping通,看看是不是ip写的不对
客户端的程序需要用,服务器端的ip,如果在同一台电脑上一般用(1270……或者localhost),如果是另外一台电脑,首先你要找到另外一台电脑的ip(这个可以到百度搜),我常用的方式是在服务器端运行cmd,然后输入命令 ipconfig ,找到ipv4的ip

Java实现聊天室可以采用网络编程中的Socket和ServerSocket技术来实现。具体实现步骤如下:

服务器端创建ServerSocket对象,并指定一个端口号来监听客户端的连接请求。

客户端创建Socket对象,并指定服务器端的IP地址和端口号来连接服务器。

服务器端通过ServerSocketaccept()方法等待客户端的连接请求,当有新的连接请求到达时,创建一个新的线程来处理该客户端的请求,并将该线程加入到线程池中。

客户端连接服务器后,通过SocketgetInputStream()方法获取输入流,并通过SocketgetOutputStream()方法获取输出流,向服务器发送消息或接收来自服务器的消息。

服务器端通过线程池中的线程来处理客户端的请求,服务器可以实现广播功能,将接收到的客户端消息转发给其他所有客户端,也可以实现点对点的私聊功能。

当客户端退出聊天室时,需要关闭相应的Socket连接,并通知其他客户端该客户端已经离开。

聊天室中的消息可以使用特定的格式进行编码和解码,以便服务器端和客户端可以正确地解析和处理消息。

需要注意的是,在实现聊天室时需要考虑线程安全、消息编解码、异常处理等问题,以确保聊天室的稳定和可靠性。同时,还需要进行充分的测试和优化,以提高聊天室的性能和用户体验。

package comkumimhrservertest;
import javanet;
import javanio;
import javaniochannels;
import javaniocharset;
import javaawt;
import javaawtevent;
public class ChatClient {
private SocketChannel sc = null;
private String name = null;
private Frame f;
private TextArea ta;
private TextField tf;
private boolean runnable = true;
public static void main(String[] args){
ChatClient cc = new ChatClient();
cccreateUI();
ccinputName();
ccconnect();
new ReceiveThread(cc,ccgetTextArea())start();
}
public SocketChannel getSc(){
return sc;
}
public void setName(String name){
thisname = name;
}
public TextArea getTextArea(){
return ta;
}
public TextField getTextField(){
return tf;
}
public boolean getRunnable(){
return runnable;
}
public void stop(){
runnable = false;
}
public void shutDown(){
try{
scwrite(ByteBufferwrap("bye"getBytes("UTF-8")));
taappend("Exit in 5 seconds!");
thisstop();
Threadsleep(5000);
scclose();
}catch(Exception e){
eprintStackTrace();
}
Systemexit(0);
}
public void createUI(){
f = new Frame("Client");
ta = new TextArea();
tasetEditable(false);
tf = new TextField();
Button send = new Button("Send");
Panel p = new Panel();
psetLayout(new BorderLayout());
padd(tf,"Center");
padd(send,"East");
fadd(ta,"Center");
fadd(p,"South");
MyClientListener listener = new MyClientListener(this);
sendaddActionListener(listener);
tfaddActionListener(listener);
faddWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
ChatClientthisshutDown();
}
});
fsetSize(400,400);
fsetLocation(600,0);
fsetVisible(true);
tfrequestFocus();
}
public boolean connect(){
try{
sc = SocketChannelopen();
//"zlg"为目标计算机名
InetSocketAddress isa = new InetSocketAddress("192168143",8814);
scconnect(isa);
scconfigureBlocking(false);
scwrite(ByteBufferwrap(namegetBytes("UTF-8")));
}catch(Exception e){
eprintStackTrace();
}
return true;
}
public void inputName(){
String name = javaxswingJOptionPaneshowInputDialog("Input Your Name:");
thissetName(name);
fsetTitle(name);
}
}
class MyClientListener implements ActionListener{
private ChatClient client;
public MyClientListener(ChatClient client){
thisclient = client;
}
public void actionPerformed(ActionEvent e){
TextField tf = clientgetTextField();
String info = tfgetText();
if(infoequals("bye")){
clientshutDown();
}else{
try{
clientgetSc()write(ByteBufferwrap(infogetBytes("UTF-8")));
}catch (Exception e1) {
e1printStackTrace();
}
}
tfsetText("");
tfrequestFocus();
}
}
class ReceiveThread extends Thread{
private ChatClient client;
private TextArea ta;
public ReceiveThread(ChatClient client,TextArea ta){
thisclient = client;
thista = ta;
}
public void run(){
SocketChannel sc = clientgetSc();
ByteBuffer byteBuffer = ByteBufferallocate(2048);
CharBuffer charBuffer = null;
Charset charset = CharsetforName("UTF-8");
CharsetDecoder decoder = charsetnewDecoder();
String msg = null;
int n = 0;
try{
while(clientgetRunnable()){
n = scread(byteBuffer);
if(n>0){
byteBufferflip();
charBuffer = decoderdecode(byteBuffer);
msg = charBuffertoString();
taappend(msg + "\n");
}
byteBufferclear();
Threadsleep(500);
}
}catch(Exception e){
eprintStackTrace();
Systemexit(0);
}
}
}
import javaio;
import javanio;
import javaniochannels;
import javaniocharset;
import javanet;
import javautil;
public class ICQServer {
private Selector selector = null;
private ServerSocketChannel ssc = null;
//服务器端通信端口号
private int port = 8814;
//在线用户列表
private Hashtable<String, SocketChannel> userList = null;
public ICQServer() {}
public ICQServer(int port) {
thisport = port;
}
//初始化服务器
public void init() {
try {
//创建选择器对象
selector = Selectoropen();
//创建ServerSocketChannel
ssc = ServerSocketChannelopen();
//设置ServerSocketChannel为非阻塞模式
sscconfigureBlocking(false);
InetAddress ip = InetAddressgetLocalHost();
Systemoutprintln("主机地址 --------> " + ip);
InetSocketAddress isa = new InetSocketAddress(ip, port);
//将与本通道相关的服务器套接字对象绑定到指定地址和端口
sscsocket()bind(isa);
//创建在线用户列表
userList = new Hashtable<String, SocketChannel> ();
}
catch (IOException e) {
Systemoutprintln("初始化服务器时异常,原因 --------> " + egetMessage());
}
}
//启动服务器
public void start() {
try {
//将ServerSocketChannel注册到Selector上,准备接收新连接请求
SelectionKey acceptKey = sscregister(selector, SelectionKeyOP_ACCEPT);
SocketChannel sc;
int n;
String name; //用户名
String msg; //用户发言信息
while (true) {
//选择当前所有处于就绪状态的通道所对应的选择键,并将这些键组成已选择键集
n = selectorselect(); //n为已选择键集中键的个数
if (n > 0) {
//获取此选择器的已选择键集。
Set readyKeys = selectorselectedKeys();
Iterator it = readyKeysiterator();
//遍历当前已选择键集
while (ithasNext()) {
SelectionKey key = (SelectionKey) itnext();
//从当前已选择键集中移除当前键,避免重复处理
itremove();
//如果当前键对应的通道已准备好接受新的套接字连接
if (keyisAcceptable()) {
//获取当前键对应的可选择通道(ServerSocketChannel)
ssc = (ServerSocketChannel) keychannel();
//接收新的套接字连接请求,返回新建的SocketChannel
sc = (SocketChannel) sscaccept();
//如果有新用户接入
if (sc != null) {
//接收新上线用户姓名
name = readMessage(sc);
//设置新建的SocketChannel为非阻塞模式
scconfigureBlocking(false);
//将新建的SocketChannel注册到Selector上,准备进行数据"写" *** 作,
//并将当前用户名以附件的方式附带记录到新建的选择键上。
SelectionKey newKey = scregister(selector,
SelectionKeyOP_WRITE, name);
//将新上线用户信息加入到在线用户列表
userListput(name, sc);
//发送"新用户上线"通知
transmitMessage(name + " in!", "--Server Info--");
}
}
//否则,如果当前键对应的通道已准备好进行"写" *** 作
else if (keyisWritable()) {
//获取当前键对应的可选择通道(SocketChannel)
sc = (SocketChannel) keychannel();
//接收该通道相应用户的发言信息
msg = readMessage(sc);
//获取选择键上附带记录的当前用户名
name = keyattachment()toString();
//如果用户提出要下线
if (msgequals("bye")) {
//从在线用户列表中移除当前用户
userListremove(name);
//注销当前选择键对应的注册关系
keycancel();
//关闭当前可选择通道
scclose();
//发送"用户下线"通知
transmitMessage(name + " out!", "--Server Info--");
}
//否则,如果接收到的用户发言信息非空("")
else if (msglength() > 0) {
//转发用户发言信息
transmitMessage(msg, name);
}
}
}
}
//延时循环,降低服务器端处理负荷
Threadsleep(500);
}
}
catch (Exception e) {
Systemoutprintln("启动服务器时异常,原因 --------> " + egetMessage());
}
}
//转发用户发言信息
public void transmitMessage(String msg, String name) {
try {
ByteBuffer buffer = ByteBufferwrap( (name + ":" + msg)getBytes("UTF-8"));
//将字节数组包装到缓冲区中
Collection channels = userListvalues();
SocketChannel sc;
for (Object o : channels) {
sc = (SocketChannel) o;
scwrite(buffer);
//将缓冲区数据写入聊天面板(TextArea)
bufferflip();
//将缓冲区ByteBuffer的极限值设置为当前数据实际大小,将缓冲区的值设置为0
}
}
catch (Exception e) {
Systemoutprintln("转发用户发言信息时异常,原因 --------> " + egetMessage());
}
}
//接收用户发言信息
public String readMessage(SocketChannel sc) {
String result = null;
int n = 0;
ByteBuffer buf = ByteBufferallocate(1024);
try {
n = scread(buf);
bufflip();
Charset charset = CharsetforName("UTF-8");
CharsetDecoder decoder = charsetnewDecoder();
CharBuffer charBuffer = decoderdecode(buf);
result = charBuffertoString();
}
catch (IOException e) {
Systemoutprintln("接收用户发言信息时异常,原因 --------> " + egetMessage());
}
return result;
}
public static void main(String args[]) {
ICQServer server = new ICQServer();
serverinit();
serverstart();
}
}

两个客户端发送消息,是通过服务器来处理的

建议你查看百度云推送,或者极光推送,都是免费

他们的推送技术有个叫推聊的功能就可以直接推送给指定的客户端

你不需要去实现这种逻辑

当然如果你非要用自己服务器去做的话,也是可以的,以下给你提供思路:

用长连接或者java sokcet 即所有客户端都和服务器保持连接,一但有数据写入就向客户端发送数据

用轮询,即客户端定时去查消息,例如A向B发消息,首先把数据写到服务器,B去查服务器就能查出来了


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13348905.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-19
下一篇 2023-07-19

发表评论

登录后才能评论

评论列表(0条)

保存