Java通信的实现

java通信其实入门还是很容易的,会ServerSocketsocketIO流就行了。

一、Java通信的原理、概念

某台设备的进程的端口<------>服务器<------->某台设备的进程的端口

无论什么进程,都会在电脑上开启一个或多个端口。不管是QQ这类交互软件,还是杀毒软件对其他应用的操作,通信的本质就是这台电脑上的进程端口与另一台(或本台)电脑上进程端口之间的交互。

此外,手机也可以与电脑进行交互。比如说我后来实现的手机控制电脑,本质上就是手机上的一个进程对电脑的一个进程进行通信。

那么如何精准定位到是这个手机(电脑)和这台电脑(其他设备)呢?

IP地址和端口。可以说,一个ip地址能确定一台电脑,端口则能确定这台电脑上的一个进程。而IP地址又有局域网ip和公网ip,区别就是局域网ip只能在同个局域网里相互访问,而公网ip则不受此限制

查看局域网ip:Windows系统cmd中输入“ipconfig”,

Linux或Mac系统输入“ifconfig”。

查看公网ip:浏览器地址输入” ip.chinaz.com/getip.asp”。

当然,方法还有许多。

其实,一台电脑是可以直接与另一台电脑进行通信(不需要服务端),但我们这里不提,我们要用服务端来作为中转站

二、实现:

1、 服务端开启一个(或多个)端口号,来供客户端连接。

             ServerSocket ss1 = new ServerSocket(7779);
             ServerSocket ss2 = new ServerSocket(7778)

注意:括号里是端口号(port),在同一台设备上不能被同时使用。这里可以用1024到 65535一定要确保你使用的端口号没被其他进程占用。可以在cmd下输入netstat查看端口的使用情况。

2、 接着使用socket阻塞,来等待客户端连接。

               Socket conn1=ss1.accept();
               Socket conn2=ss2.accept();

思考一下:

(1)       Socket conn1= ss2.accept();
             Socket conn2= ss1.accept();
(2)       Socket conn1= ss1.accept();
             Socket conn2= ss1.accept();
(3)       Socket conn1= ss2.accept();
(4)       Socket conn1= ss1.accept();
             Socket conn2= ss2.accept();
             Socket conn3= ss1.accept();

上述都是可行的,ServerSocket与Socket之间并没有数量限制,根据情况来使用。只是 要注意服务端要与客户端socket连接一一对应好。

3、 服务端并不只是为一个客户端服务的,它应该能接受许多客户端的连接。那要怎么做呢?我们可以用多线程来实现。

   while(true){
         Socket conn1= ss1.accept();
         Socket conn2= ss2.accept();
         Client client=new Client(conn1,conn2);
         Thread th=new Thread(client);
         th.start();
    }

4、 当一个客户端连接到服务端的时候,socket将它们进行了连接,那要怎么成功通信呢?我们要用到IO流。IO的相关类有很多,我建议用DataInputStream和DataOutputStream。其实别的也很不错,建议选择一两个精用就行了。

      DataInputStream dis1 = new DataInputStream(conn1.getInputStream());
      DataInputStream dis2 = new DataInputStream(conn2.getInputStream());
      DataOutputStream dos1 = new DataOutputStream(conn1.getOutputStream());
      DataOutputStream dos2 = new DataOutputStream(conn2.getOutputStream());

它们提供的方法,主要是传递相应的基本类型和string,还是挺好用的。

DataInputStream提供的方法: write(); writeChar(); writeInt(); writeFloat(); writeDouble(); writeUTF();等等
DataOutputStream提供的方法: read(); readChar(); readInt(); readFloat(); readDouble(); readUTF();等等

这些write方法要注意的是,最好在写入完成后加上flush()方法

示例:

      dis.writeInt(size);
      dis.write(数组);
      dis.writeUTF(“Success!”);
      dis.flush();

而各种read()方法跟ServerSocket的accept()方法相似,都是堵塞状态,只有当读取到数据时,才会往下执行代码

通信的内容无非是 数字、字符、字符串、图片、音乐、视频等等。前边的基础类型直接传就行了,而后边的多媒体类型先转化为基础类型数组,再进行传输。转化并不难,几行代码就解决了。因为情况太多种,这里就不赘述了,自行百度吧。

最后,说一下IO流的关闭方法。对象名.close(); 就行了。

5、我们在实现以上代码的时候,基本都要用try()和catch()或throw来捕获异常,这部分代码加上就是了。

当客户端意外退出或正常退出时,假如你用的软件拼命报错,你可以看一下catch语句中是否有e.printfstack();之类的代码。去掉就行了。

但这肯定不是治本的,你要根据具体情况(即你的需求)来关闭IO流、关闭socket、甚至直接close对应的线程。常用的方法是通过改变某个参数+判断来回避一些代码的执行

6、 有那么多的客户端,服务端要如何来辨识并且精准地建立两者或多者之间的联系呢?

每个客户端在连接到服务端后可以output一条独特的消息,或者服务端通过客户端的ip地址来辨别。

在不用数据库的情况下,可以采用数组或ArrayList来存储接入的客户端。要特别注意一下,当客户端退出时,要在相应的数组或队列中移除该客户端

7、 在代码、技术之外,更重要的是要知道目的是什么,思路是什么,实现的步骤或措施是什么,什么时候要output、input,顺序如何弄,通信的步骤是否对应。要想弄出能服务于千万甚至上亿级别的程序,一定要想好各种异常情况,并进行处理。除了提高程序的容错性外,还要在封装上多注意,学习设计模式,加强代码的可读性和易改性。

8、socket在多种语言上都是可用的,IO流可能是有问题的(滑稽),比如InputStream提供的方法write()、read()中,传参的是int,但真正传的是int的后八位。又如读取字符串的一些方法,也是可能有问题的,在Android上,问题更多了。所以,提醒一下,类提供的方法不总是可靠的,别太相信了。想实现java通信也不是很难的事,别怂!

9、java通信能实现什么产品,我最后来抛砖引玉一下。产品一定要动手做,不然就不算学。只要是程序与程序之间的交互都能用到java通信。比如在线游戏、仿聊天室,又比如我后来写的手机控制电脑。(其实我就是想给我下篇技术文章打广告,嘎嘎)

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值