这学期开始接触了java中网络通信这方面的知识,对于网络通信的感觉由原来的那种感觉不可思议慢慢的发生了改变,感觉网络通信并不是原来想象的那么神奇,虽然不知道最底层那些数据是以怎么样的一种方式去传送的,或者说现在并不了解网络通信最初原始的原理是怎么样的,这些自己也还没有动手去查资料了解。但基于java这种语言,用它已经建好的一系列类和方法,我们便可以很好的利用这些工具来开发一些网络通信这方面的东西了(自己也利用这些知识实现了网络五子棋,网络画图板、简单的聊天工具、和文件的传输)。
我们知道网络通信,既然是通信他就不再局限于一台机器上的数据传送,他实现了不同机器上的数据传输。现在开始介绍一下,java中时怎么去实现通信的。从简单入手、实现一个客服端和服务器之间的简单通信。
客服端和服务器能实现连接和通信的条件:客服端的创建需要知道它所连接的服务器的ip和端口号。服务器的创建需要一个端口号。至于ip可能大家比较清楚,我们知道每一台其计算机都有一个独一无二的ip地址,之所以为什么?这个很容易理解每不同的ip对应一台计算机才能实现数据的准确传输,只要你ip弄对了就不会发生你想把数据发送到A但却却发送到B这样的问题。而端口号又是什么呢?用ip类比,ip相当于一台计算机,而端口号就相当于一台电脑上一个程序,你要给一台计算机上的某一个程序发送数据,不仅仅要知道这台计算机的在哪里,还要知道这个程序在哪里。即你要知道ip(计算机的位置),和端口号(程序的位置)。再做一个类比,ip相当于一个酒店名,而他端口号就是这个就酒店房间的房间号。这样只要有了这两个信息我们就能很容易的找到我们要找的房间。
说了这么多,如何用java代码编程实现通信了。这个是这边文章所要讲的重点内容。
我们知道java中就是利用一个个类实例化的一个个对象,并调用他们所特有的方法来实现完成一个软件的开发的。当然通信也不例外。
服务器的创建就是实例化一个ServerSocket类的一个对象。如下我们定义一个创建服务器的方法。
/**
* 创建服务器的方法
* @param port端口号
*/
public void creat_server(int port){
try {
//实例化服务器对象
ServerSocket server=new ServerSocket(port);
System.out.println("服务器启动成功,等待客服端连接、、、");
} catch (IOException e) {
e.printStackTrace();
}
}
这样一个非常简单的客户端和服务器就建立起来了。
那么该如何去实现我们建立起来的客户端和服务器的数据传输呢?这个是通信的重点所在。
如上面所讲有了独一无二的ip和特定的端口号我们能让客户端很容易的找它所要连接的服务器。那么怎么样让客户端和服务器连接起来呢?这个很简单,只要调用我们上面建好的服务器对象server调用它等待客户端连接的方法accept(),就行了.
即Socket client=server.accept();
这是一个会阻塞的方法,所谓的阻塞就是当程序运行到这段代码的时候会停在这边,即等待到有相应的客户端程序运行起来,这句代码下面的代码才能被执行。
要是还不懂,做一个小测试。
Public class Test{
Public static void main(String [] args){
try {
//实例化服务器对象
ServerSocket server=new ServerSocket(9090);
System.out.println("服务器启动成功,等待客服端连接、、、");
//等待客服端连接
Socket client=server.accept();
System.out.println("连接服务器成功了!!!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
把这个程序运行起来,下面的输出语句并没有被打印出来,因为上面server.accept();这个方法阻塞住了代码的执行。想要让他执行起来,只要有相应的客户端程序运行起来就行。
如在一个主函数中运行我们上面写的创建客户端的代码。就能在控制台看到我们打印出来的东西了。需要注意的是创建客户端的端口号要和服务器的端口号对应起来,也就是上面的9090。这边就不多做测试,留给你们自己动手。
这样我们就实现了客户端和服务器之间的连接了。
那么接下来就是讲讲他们之间的交流了。
I/o流我们都知道。(但大多人都没有很好的去解析java中的流,包括本人,所以在学通信过程中很多由于流而产生的问题都没有去真正解决,或者是解决了但却不知道所以然)。
其实java通信过程简单的说就是流之间传送数据的过程、流的输入和输出过程。
那么我们就必须从客户端和服务器中获取输入输出流。这个很容易。
从我们上面实例化的客户端client对象中调用它的方法便能获取流。
即:InputStream in=client.getInputStream();
OutputStream out=client.getOutputStream();
服务器和客户端两端的流都是这样获取的。
获取了流,那么下面就可以利用流来实现客户端和服务器之间的数据传输了。
比如用客户端这边的输出流out执行这样一句代码:
out.write(10);
意思就是从客户端向服务器发送10这个整形数据。
那么以之相应的是服务器端执行代码:
int i=In.read();
那么这样服务器就读取了客户端所发送过来的数据。这样是否能准确传送客户端和服务器之间的数据呢?我们下面来做个测试。
服务器:
Public class Test{
Public static void main(String [] args){
try {
// 实例化服务器对象
ServerSocket server= new ServerSocket(9090);
// 等待客服端连接
Socket client=server.accept();
System.out.println("服务器启动成功,等待客服端连接、、、");
InputStream in=client.getInputStream();
OutputStream out=client.getOutputStream();
int i=0;
while(true){
i=in.read();
System.out.println("客户端发送过来的数据是:"+i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
客服端:
Public class Test2{
Public static void main(String [] args){
try {
// 实例化客服端对象
Socket client= new Socket ("localhost",9090);
InputStream in=client.getInputStream();
OutputStream out=client.getOutputStream();
int i=0;
while(true){
i++;
out.write(i);
Thread.sleep(1000);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
先运行服务器,在运行客户端,这样我们就可以从控制台看到打印出来如下:
客户端发送过来的数据是:1
客户端发送过来的数据是:2
客户端发送过来的数据是:3
客户端发送过来的数据是:4
。。。。。。。。
客户端发送过来的数据是:254
客户端发送过来的数据是:255
客户端发送过来的数据是:0
客户端发送过来的数据是:1
客户端发送过来的数据是:2
为什么255后面不是256??
即用out.write(256);
单用int i=in.read();接收到的却是0;
这个问题我实在做网络画图板的时候发现的。比如说要在客户端画上一条直线,在服务器上能把这条直线显示出来。那么就必须把直线的四个坐标点传过去。四个坐标点都是整形,坐标点有很多大于255的,所以用上面的方法就出现了这样的问题,当你四个坐标点都不大于255的时候直线在服务器上画出来是和客户端一模一样的,也就是数据正确传送了。但但出现大于255的时候两条直线就差别很大了。这究竟是为什么呢?
下面给你解答:
由于OutputStream和InputStream这两种流在传输过程中是以一个字节为单位的。一个字节8个位所以最大只能传送2^8-1=255;当超过255它就自动截取低8位,比如256写成二进制是100000000,它就截取了8个0,所以服务器那边接收到的就是0了。
相信这样并不难理解。
发现了是由于这样的原因造成的,那么怎么去解决这个问题呢?
知道了原因去解决问题是不难的。
我们在传送整形数据之间可以先计算他的字节数,先发送字节数(有几个字节)给服务器,然后将它拆分成一个个字节,用for循环再用out.write();去发送数据;在接收到先收到它的字节数,然后相应的用for循环来把一个个字节接收过来。在并起来,两者是一个逆过程。这个我们就要自己去实现几个方法:
发送端:
1.获取一个整形数据对应的二进制的字节数。
2.获取一个整形数据对象的二进制字符串,不足8的倍速补零。
这样我们就能截取一个个8位字节去发送了。
接收端:
1.根据获取的字节数来计算相应的整形数据。
比如发送端发送256,那么接收到会接收到2个字节,第一个字节获取的整形数据是0,第二是1,但第二个要相应乘于2^8,也就是256,然后两者相加。这样就能获得了。相信这样并不难懂。要是有三个字节。那么获取的第三个整形数据要乘以2^16在加上前面两个字节对应的整形数据。
以上方法我们是基于InputStream和OutputStream流加上我们对问题的理解自定义的能准确传送比较大的整形数据的方法。显然十分的麻烦。其实有更简单的方法,用java中写好的类和封装好的方法可以非常容易的实现大型整形数据的传送。(他的底层操作或许就是我上面所说的哦!!!!)
Java中提供了数据流DataInputStream和DataOutputStream这两个数据流
他们有writeInt(),和相应的readInt()方法;你写入一个什么样的整形他就会相应读取到什么整形数。在实例化数据流的对象时只要把我们上面获取的in和out流对象作为参数,便可以建立两者之间的联系了。
如DaraOutputStream dataout=new DataOutputStream(out);这样就行了。具体测试就有兴趣的可以自己去测试一下。
有了上面这些知识,去实现一个简单的网络画图板、网络五子棋、还有文件的传送和聊天工具就不难了、有兴趣的同学可以去实践一下。
关于java网络通信编程这边就略作介绍这些。后面关于我在利用java网络通信编程在写自己小项目遇到的问题和我如何去解决在做介绍。
分享到:
相关推荐
免费JAVA毕业设计 2024成品源码+论文+录屏+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
免费JAVA毕业设计 2024成品源码+论文+录屏+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
1、文件内容:perl-Class-Load-0.20-3.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/perl-Class-Load-0.20-3.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
FCN实现斑马线分割(含数据集)
,西门子200smart控制3轴伺服程序,plc程序结构条理清晰,层次分明,注释齐全。 西门子触摸屏程序画面功能齐全,画面精美。 有io图。 电气原理图。 参考本案例程序。 可快速掌握西门子200smart控制伺服编程技巧,扩展自己的编程逻辑思维。 节省大量不必要花费的时间,可快速上手。
资源说明: 1:csdn平台资源详情页的文档预览若发现'异常',属平台多文档切片混合解析和叠加展示风格,请放心使用。 2:29页图文详解文档(从零开始项目全套环境工具安装搭建调试运行部署,保姆级图文详解),旨在为更多的人甚至零基础的人也能运行、使用和学习。 3:配套毕业论文,万字长文,word文档,支持二次编辑。 4:范例参考答辩ppt,pptx格式,支持二次编辑。 5:工具环境、ppt参考模板、相关电子教程、视频教学资源分享。 6:资源项目源码均已通过严格测试验证,保证能够正常运行,本项目仅用作交流学习参考,请切勿用于商业用途。 7:项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通。 内容概要: 本系统基于B/S网络结构,在IDEA中开发。服务端用Java并借Spring Boot框架搭建后台。前台采用支持HTML5的VUE框架。用MySQL存储数据,可靠性强。 能学到什么: 使用Spring Boot搭建后台。VUE框架构建前端交互界面、前后端数据交互、MySQL管理数据、从零开始环境搭建、调试、运行、打包、部署流程。
"基于ADMM算法的多微网协同优化调度策略:实现分布式电能共享与信息保护",02-基于ADMM算法的多微网协同优化调度 摘要:为了实现微网间的电能以及能量共享,采用ADMM方法,实现了微网之间的电能与协同优化,方法为分布式算法,有效的保护了各个微网的信息,避免了集中优化的大量信息索取。 ,基于ADMM算法; 多微网; 协同优化调度; 分布式算法; 能量共享; 信息保护,基于ADMM算法的微网协同优化调度方案
b站弹幕格式转换 xml转ass
.NET SDK Senparc.Weixin for C# .NET Framework .NET Core.NET 8.0/JSSDK WeChat SDK for C#. github官网 github官网 github官网 github官网 github官网
ollama基础知识简介.md
免费JAVA毕业设计 2024成品源码+论文+录屏+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
,fx3u和西门子v20 台达vfd-m 三菱E700 rtu所需硬件:FX3U PLC,FX3U-485BD通信板,变频器。 功能:使用fx3u-485bd板,rtu通信控制西门子v20 台达VFD-M 三菱E700三种变频器正反转,停止,频率设定,加减速,以及对频率,电压,电流的读取,有运行指示,效果可以看视频,反应及时,运行可靠,三种变频器程序是单个的,非三台一起控制。 的内容包括程序,接线,参数说明
软件渲染器tinyrenderer
电脑调音软件下载是专为汽车音响爱好者和专业人士设计的一款强大工具, 这款软件的主要功能在于帮助用户对车载音频系统进行精确的数字信号处理,以提升音乐播放效果,提供更丰富的听觉体验。
1、文件内容:perl-Date-Calc-6.3-14.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/perl-Date-Calc-6.3-14.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
给山东大学软件学院的学弟学妹们使用
生成式对抗网络在金融数据中的应用
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
资源说明: 1:csdn平台资源详情页的文档预览若发现'异常',属平台多文档切片混合解析和叠加展示风格,请放心使用。 2:29页图文详解文档(从零开始项目全套环境工具安装搭建调试运行部署,保姆级图文详解),旨在为更多的人甚至零基础的人也能运行、使用和学习。 3:配套毕业论文,万字长文,word文档,支持二次编辑。 4:配套答辩ppt,pptx格式,支持二次编辑。 5:工具环境、ppt参考模板、相关电子教程、视频教学资源分享。 6:资源项目源码均已通过严格测试验证,保证能够正常运行,本项目仅用作交流学习参考,请切勿用于商业用途。 7:项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通。 内容概要: 本系统基于B/S网络结构,在IDEA中开发。服务端用Java并借Spring Boot框架搭建后台。前台采用支持HTML5的VUE框架。用MySQL存储数据,可靠性强。 能学到什么: 使用Spring Boot搭建后台。VUE框架构建前端交互界面、前后端数据交互、MySQL管理数据、从零开始环境搭建、调试、运行、打包、部署流程。
内容概要:文章详细介绍了计算机二级和软考两类计算机认证考试的习题资源获取途径及相关备考建议。对于计算机二级考试,提供了官方教材与配套习题、在线题库、专业论坛、培训机构等多种渠道的习题来源介绍。而对于软考,则提及了官方指南与教程、历年真题及其解析、在线学习资源和各类辅导书籍等方面的习题资源,并阐述这些资源对于考生熟悉考试题型、检验学习成果的重要性。最后提出了如制定备考计划、多做练习、注意理解和模拟考试这四大备考要点。 适用人群:准备报考全国计算机等级考试二级或者软考的技术人员或学生群体。 使用场景及目标:旨在为备考人员提供全面有效的习题资源收集方式和支持性建议,助力他们高效备考并通过考试。 其他说明:文中特别强调理解知识点而非单纯记忆、利用各种线上线下的辅助工具和材料来加强对知识的掌握,还有就是实战演练的作用不可忽视。