当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]基于socket的Java网络编程集粹

事实上网络编程简单的理解就是两台计算机相互通讯数据而已,对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了,JavaSDK提供一些相对简单的Api来完成这些工作。Socket就是其中之一,对于Java而言,这些Api存在与java.net这个包里面,因此只要导入这个包就可以准备网络编程了。

网络编程的基本模型就是客户机到服务器模型,简单的说就是两个进程之间相互通讯,然后其中一个必须提供一个固定的位置,而另一个则只需要知道这个固定的位置。并去建立两者之间的联系,然后完成数据的通讯就可以了,这里提供固定位置的通常称为服务器,而建立联系的通常叫做客户端,基于这个简单的模型,就可以进入网络编程啦。

Java对这个模型的支持有很多种Api,而这里我只想介绍有关Socket的编程接口,对于Java而言已经简化了Socket的编程接口。首先我们来讨论有关提供固定位置的服务方是如何建立的。Java提供了ServerSocket来对其进行支持.事实上当你创建该类的一个实力对象并提供一个端口资源你就建立了一个固定位置可以让其他计算机来访问你,ServerSocketserver=newServerSocket(6789);这里稍微要注意的是端口的分配必须是唯一的。因为端口是为了唯一标识每台计算机唯一服务的,另外端口号是从0~65535之间的,前1024个端口已经被Tcp/Ip作为保留端口,因此你所分配的端口只能是1024个之后的。好了,我们有了固定位置.现在所需要的就是一根连接线了.该连接线由客户方首先提出要求。因此Java同样提供了一个Socket对象来对其进行支持,只要客户方创建一个Socket的实例对象进行支持就可以了。Socketclient=newSocket(InetAddress.getLocalHost(),5678);客户机必须知道有关服务器的IP地址,对于着一点Java也提供了一个相关的类InetAddress该对象的实例必须通过它的静态方法来提供,它的静态方法主要提供了得到本机IP和通过名字或IP直接得到InetAddress的方法。

上面的方法基本可以建立一条连线让两台计算机相互交流了,可是数据是如何传输的呢?事实上I/O操作总是和网络编程息息相关的。因为底层的网络是继续数据的,除非远程调用,处理问题的核心在执行上,否则数据的交互还是依赖于IO操作的,所以你也必须导入java.io这个包.java的IO操作也不复杂,它提供了针对于字节流和Unicode的读者和写者,然后也提供了一个缓冲用于数据的读写。

BufferedReaderin=newBufferedReader(newInputStreamReader(server.getInputStream()));

PrintWriterout=newPrintWriter(server.getOutputStream());

上面两句就是建立缓冲并把原始的字节流转变为Unicode可以操作,而原始的字节流来源于Socket的两个方法,getInputStream()和getOutputStream()方,分别用来得到输入和输出,那么现在有了基本的模型和基本的操作工具,我们可以做一个简单的Socket例程了。

服务方:

importjava.io.*;

importjava.net.*;

publicclassMyServer{

publicstaticvoidmain(String[]args)throwsIOException{

ServerSocketserver=newServerSocket(5678);

Socketclient=server.accept();

BufferedReaderin=newBufferedReader(newInputStreamReader(client.getInputStream()));

PrintWriterout=newPrintWriter(client.getOutputStream());

while(true){

Stringstr=in.readLine();

System.out.println(str);

out.println("hasreceive....");

out.flush();

if(str.equals("end"))

break;

}

client.close();

}

}

这个程序的主要目的在于服务器不断接收客户机所写入的信息只到,客户机发送"End"字符串就退出程序,并且服务器也会做出"Receive"为回应,告知客户机已接收到消息。

客户机代码:

importjava.net.*;

importjava.io.*;

publicclassClient{

staticSocketserver;

publicstaticvoidmain(String[]args)throwsException{

server=newSocket(InetAddress.getLocalHost(),5678);

BufferedReaderin=newBufferedReader(newInputStreamReader(server.getInputStream()));

PrintWriterout=newPrintWriter(server.getOutputStream());

BufferedReaderwt=newBufferedReader(newInputStreamReader(System.in));

while(true){

Stringstr=wt.readLine();

out.println(str);

out.flush();

if(str.equals("end")){

break;

}

System.out.println(in.readLine());

}

server.close();

}

}

客户机代码则是接受客户键盘输入,并把该信息输出,然后输出"End"用来做退出标识。

这个程序只是简单的两台计算机之间的通讯,如果是多个客户同时访问一个服务器呢?你可以试着再运行一个客户端,结果是会抛出异常的。那么多个客户端如何实现呢?

其实,简单的分析一下,就可以看出客户和服务通讯的主要通道就是Socket本身,而服务器通过accept方法就是同意和客户建立通讯.这样当客户建立Socket的同时。服务器也会使用这一根连线来先后通讯,那么既然如此只要我们存在多条连线就可以了。那么我们的程序可以变为如下:

服务器:

importjava.io.*;

importjava.net.*;

publicclassMyServer{

publicstaticvoidmain(String[]args)throwsIOException{

ServerSocketserver=newServerSocket(5678);

while(true){

Socketclient=server.accept();

BufferedReaderin=newBufferedReader(newInputStreamReader(client.getInputStream()));

PrintWriterout=newPrintWriter(client.getOutputStream());

while(true){

Stringstr=in.readLine();

System.out.println(str);

out.println("hasreceive....");

out.flush();[!--empirenews.page--]

if(str.equals("end"))

break;

}

client.close();

}

}

}

这里仅仅只是加了一个外层的While循环,这个循环的目的就是当一个客户进来就为它分配一个Socket直到这个客户完成一次和服务器的交互,这里也就是接受到客户的"End"消息.那么现在就实现了多客户之间的交互了。但是.问题又来了,这样做虽然解决了多客户,可是是排队执行的。也就是说当一个客户和服务器完成一次通讯之后下一个客户才可以进来和服务器交互,无法做到同时服务,那么要如何才能同时达到既能相互之间交流又能同时交流呢?很显然这是一个并行执行的问题了。所以线程是最好的解决方案。

那么下面的问题是如何使用线程.首先要做的事情是创建线程并使得其可以和网络连线取得联系。然后由线程来执行刚才的操作,要创建线程要么直接继承Thread要么实现Runnable接口,要建立和Socket的联系只要传递引用就可以了.而要执行线程就必须重写run方法,而run方法所做的事情就是刚才单线程版本main所做的事情,因此我们的程序变成了这样:

importjava.net.*;

importjava.io.*;

publicclassMultiUserextendsThread{

privateSocketclient;

publicMultiUser(Socketc){

this.client=c;

}

publicvoidrun(){

try{

BufferedReaderin=newBufferedReader(newInputStreamReader(client.getInputStream()));

PrintWriterout=newPrintWriter(client.getOutputStream());

//MutilUserbutcanparallel

while(true){

Stringstr=in.readLine();

System.out.println(str);

out.println("hasreceive....");

out.flush();

if(str.equals("end"))

break;

}

client.close();

}catch(IOExceptionex){

}finally{

}

}

publicstaticvoidmain(String[]args)throwsIOException{

ServerSocketserver=newServerSocket(5678);

while(true){

//transferlocationchangeSingleUserorMultiUser

MultiUsermu=newMultiUser(server.accept());

mu.start();

}

}

}

我的类直接从Thread类继承了下来.并且通过构造函数传递引用和客户Socket建立了联系,这样每个线程就有了。一个通讯管道.同样我们可以填写run方法,把之前的操作交给线程来完成,这样多客户并行的Socket就建立起来了。

以上的代码使用的是

BufferedReaderin=newBufferedReader(newInputStreamReader(client.getInputStream()));

PrintWriterout=newPrintWriter(client.getOutputStream());

还有一种方法是使用

DataInputStreamisFromClient=newDataInputStream(client.getInputStream());

DataOutputStreamosToClient=newDataOutputStream(client.getOutputStream());

关于这两种输入输出流的不同,我也只知道前一种对字符串支持比较好,后面对于读取一个字符串需要处理,但是可以支持很多种类型的输出。对于传递字符串而言前一种应该是很好的选择了

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭