LabView实现与IEDA(Java客户端)用服务器客户机模式进行通信(类似聊天)
创始人
2024-11-06 15:10:39

上一篇仿照大佬的写了一个简单的向客户机写循环变量,经过一天的探索双方终于可以进行交互了。下面进行分享。下面是最终的执行效果,上面两个调试控件碍眼请忽略

下面是程序截图

 我一点点解释它。

这个位置相当于Java为ServerSocket创建了构造函数的参数,注意是参数,并没有创建ServerSocket ,意思是这个ServerSocket监听的是哪个端口。就是一些初始化ServerSocket的参数,25000为监听端口,-1表示如果没有连接,则无限等待不超时。

这里才是创建ServerSocket,根据之前给的初始化参数。可以看到我们用一个while套着它,意思是可以监听到不同的socket连接,即可以有多个客户端连接(但是本示例没有考虑这种情况,如果有多个连接,消息会显示在一个控件中,高级语言的面向对象可以很好的解决这个问题,这里就不纠结这个了,我们只有一个Java客户端)。从 上面的那个控件UI上面有个小的W旁边的那根线就是Java中对应的Socket类对象实例,可以看到我们连接了里层的两个while循环,并通过移位寄存器反复赋值,意思就是不要销毁这个socket对象(连接)。

 在这里用了事件结构,发送按钮被按下就会跳到真里面,读取标签为‘你要发送什么’的这个控件里面的内容,通过添加开始标志‘start||’,以及结束标志‘end||’,包装后,将流推送到网络上,为什么要这么设计呢,其实一开始我也不是这么设计的,但是经过我的反复实验,只有这样,在Java端想要拿到有效数据才比较容易。在Java端建立一个1000Byte大小的数组,将来自服务器的数据全部转为字符串,用IndexOf函数得到开始标志,结束标志的位置,就可以通过String.subString()函数,传入‘start||’.length+开始标志位置,以及结束标志位置,就可以得到有效数据,即服务器发过来的数据。

此外可以看到上图还连接了一个分支,是用来在服务器端显示自己说了什么的,既然是聊天得人性化一点,将收到的和自己说的放到一个显示框,方便阅读。我们先读取原聊天控件里面的内容,加上‘服务器说:’这个标签,加上自己刚才要发的内容,加上换行符,写入显示控件中。这样控件就能正确显示自己说了什么了。

我们来看另一个分支,这个是读取客户端发过来消息的分支,首先说明,我在java端写的客户端消息统一以||**||**||结尾,这样的话更方便解析有效信息,因为目前接触到的读取函数是要指定读取多少的,我们指定为1000,和Java端保持一致,Java端如果消息长度不足1000,则将有效消息,加上结尾符号,再加一些无关紧要的东西填充至1000Byte。如果第一次消息来了,我们首先搜寻结尾符在消息中的位置,得到位置后截取字符串,然后组合字符串,组合字符串的格式为以前的消息+客户端说:+本次的消息+换行。之后写入聊天记录这个控件中,之后再把socket句柄和旧的聊天记录传给下一次循环。这样新的消息来,就能在原有消息上增加。至此程序分析完毕。

这次的尝试主要是知道了移位寄存器配合while使用可以类似于达到局部变量保持的效果,可以对于复杂的数据结构还没掌握,不然可以将socket句柄和每一个对话框这些每一个客户端,服务器的必要元素封装成一个类,这样就可以多用户和服务器聊天了。

说到这里,我发现有好多好多学习的人不明白局域网这个概念,至少大学阶段学习完计算机网络,百分之七八十不知道云服务器干什么用的,不知道公网IP的作用。这里也多啰嗦几句,我们可以使用cmd打开命令行窗口通过ipconfig-all命令看到自己的ip地址都是192.168.***.***,其实这只是个私网ip地址,设想如果你自己的ip是192.168.31.10,别人的也是,那么ip还怎么唯一索引到一台计算机呢。或许有人会问,你怎么知道我的私网地址和别人重复了,那么我想问一个问题,难道大家不好奇某品牌的新路由器(其实一定程度上只是个局域网交换机)配置地址都是192.168.31.1,为什么配置的时候不会进入别人的路由器呢。所以你那只是个私网,那公网的特征是什么呢,这个是范围的,比如我一个云服务器的例子为8.141.93.19(这里只是举个例子,这是个公网ip地址),回到这个Labview的例子,如果这个程序在这台公网上执行,那么就算服务器在(即LabView)在北京运行,你Java程序客户端在长沙,也是可以互相通信的(前提是你在我Java代码中把服务器的IP地址改为以上公网ip地址)。下面分享Java端代码。这是Main.java

import java.io.OutputStream; import java.net.Socket; import java.util.Scanner;  public class Main {     public static void main(String[] args) throws Exception{          Socket socket = new Socket("127.0.0.1", 25000);         Scanner sin=new Scanner(System.in);         new Thread(new Reader(socket)).start();         while(true){             String message=sin.nextLine();             System.out.println("客户端说:"+message);             message+="||**||**||";             OutputStream os=socket.getOutputStream();             byte[]  buffer_mess=message.getBytes();             byte[] fill_byte=new byte[1000];             System.arraycopy(buffer_mess, 0, fill_byte, 0, Math.min(buffer_mess.length, fill_byte.length));             os.write(fill_byte);             os.flush();             }         }     }

这是Reader.java

import java.io.InputStream; import java.net.Socket;  public class Reader extends Thread{     Socket socket;     public Reader(Socket socket){         this.socket=socket;     }     public void run(){         String startFlag="start||";         String endFlag="end||";         while(true){             try {                 InputStream ins=socket.getInputStream();                 int len=0;                 byte[] arr=new byte[1024];                 ins.read(arr);                 String mess=new String(arr,0,arr.length);                 int start=mess.indexOf(startFlag);                 int end=mess.indexOf(endFlag);                 start+=startFlag.length();                 mess=mess.substring(start,end);                 System.out.println("服务器说:"+mess);             } catch (Exception e) {                 throw new RuntimeException(e);             }          }     } }    

 如需要vi代码的请留言

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...