LabView实现与IEDA(Java客户端)用服务器客户机模式进行通信(类似聊天)

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

下面是程序截图

 我一点点解释它。

这个位置相当于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代码的请留言

  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值