Java网络编程

对于网络方面的知识在这里不作详细的介绍,读者可以参考《 TCP/IP详解 I II III》等网络书籍。

下面简单的谈下网络通信协议和网络通信协议接口。

网络通信协议: 计算机网络中实现通信必须有一些约定即通信协议,对速率,传输代码,代码结构, 传输控制步骤,出错控制等制定标准。
网络通信接口: 为了使两个结点之间能进行对话,必须在它们之间建立通信工具(即接口),使得彼此 之间能进行信息交换。接口包括两部分:
java中提供了两种常见的网络协议支持,TCP/UDP,关于这这两种协议,懂网络基础知识的朋友都知道这两种协议属于OSI(TCP/IP) 中运输层的协议,在TCP/IP中,把OSI简化为四层,其中运输层与应用层直接交互。

下面简单的介绍TCP/UDP协议 :
TCP: 是专门设计用于在不可靠的因特网上提供可靠的,端到端的字节流通信协议,它是一种面向连接的协议。TCP连接是字节流而非报文流。
UDP: 向应用程序提供了了一种发送封装的原始IP数据报(包,分组)的方法,并且发送时无需建立连接,是一种不可靠的连接,但是效率高,广泛的运用在视频传输,语音通话等通信中。

Socket 编程是使用最广泛的网络概念套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。当连接建立时,服务器会创建一个Socket对象。客户端和服务器现在可以通过对Socket对象的写入和读取来进行进行通信。java.net.Socket类代表一个套接字,并java.net.ServerSocket类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。
以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:
服务器实例化一个ServerSocket对象,表示通过服务器上的端口通信,该对象很像监听器,监听客户端是否有用户来连接。服务器调用 ServerSocket类 的accept()方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。服务器正在等待时,一个客户端实例化一个Socket对象,指定服务器名称和端口号来请求连接。Socket类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个Socket对象能够与服务器进行通信。在服务器端,accept()方法返回服务器上一个新的socket引用,该socket连接到客户端的socket。连接建立后,通过使用I/O流在进行通信。每一个socket都有一个输出流和一个输入流。客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。TCP是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送.以下是一些类提供的一套完整的有用的方法来实现sockets。具体方法详见
java.net包中定义的两个类Scoket和ServerScoket。 http://docs.oracle.com/javase/8/docs/api/index.html
以上client与server通信 过程可以简单的用下面的示意图来表示:
                                                                                                            Java网络编程_第1张图片

下面客户端与服务器端进行简单的 TCP协议通信:

点击(此处)折叠或打开

  1. public class TCPServer {
  2.   public static void main(String[] args){
  3.      
  4.      try {
  5.         @SuppressWarnings("resource")
  6.         ServerSocket server = new ServerSocket(11111);
  7.         Socket ser = server.accept();
  8.         DataInputStream in = new DataInputStream(ser.getInputStream());
  9.         OutputStream ou = ser.getOutputStream();
  10.         DataOutputStream out = new DataOutputStream(ou);
  11.         out.writeUTF("hi!Client!");
  12.         System.out.println(in.readUTF());
  13.         out.flush();
  14.         out.close();
  15.     } catch (IOException e) {
  16.         // TODO 自动生成的 catch 块
  17.         e.printStackTrace();
  18.     } 
  19.   }
  20. } 

  21. public class TCPClient {
  22.    public static void main(String[] args){
  23.      
  24.      try {
  25.         @SuppressWarnings("resource")
  26.         Socket client = new Socket("127.0.0.1",11111);
  27.         OutputStream out = client.getOutputStream();
  28.         DataOutputStream data = new DataOutputStream(out);
  29.         DataInputStream inn = new DataInputStream(client.getInputStream());
  30.         System.out.println(inn.readUTF());
  31.         data.writeUTF("hi!server!");
  32.         data.flush();
  33.         data.close();
  34.         inn.close();
            client.close();

  35.     } catch (UnknownHostException e) {
  36.         e.printStackTrace();
  37.     } catch (IOException e) {
  38.         e.printStackTrace();
  39.      }
  40.    }
  41. }


从上面看出,client端发出与ip为127.0.0.1,端口号为11111的服务器进行socket通信,并且对服务器端发出问候,此时服务器端的accept()正在监视11111端口,如果有socket请求,则马上建立连接,并把从客户端发来的信息打印出来,此时服务器端也向客户端发出问候,并打印结果:



上面只是简单的一对一进行通信,可以多个客户端对一个服务器端发出通信请求,  对上面的代码进行修改就可以简单实现,再添加一个客户端类TCPClient1,代码如下:

点击(此处)折叠或打开

  1. public class TCPServer {
  2.   public static void main(String[] args){
  3.      
  4.      try {
  5.          @SuppressWarnings("resource")
  6.         ServerSocket server = new ServerSocket(11111);
  7.         while(true){
  8.          Socket ser = server.accept();
  9.         DataInputStream in = new DataInputStream(ser.getInputStream());
  10.         OutputStream ou = ser.getOutputStream();
  11.         DataOutputStream out = new DataOutputStream(ou);
  12.         out.writeUTF("hi!Client!");
  13.         System.out.println(in.readUTF());
  14.         out.flush();
  15.         out.close();
  16.         }
  17.        
  18.     } catch (IOException e) {
  19.         // TODO 自动生成的 catch 块
  20.         e.printStackTrace();
  21.     } 
  22.   }
  23. } 

  24. public class TCPClient {
  25.      public static void main(String[] args){
  26.          
  27.          try {
  28.             @SuppressWarnings("resource")
  29.             Socket client = new Socket("127.0.0.1",11111);
  30.             OutputStream out = client.getOutputStream();
  31.             DataOutputStream data = new DataOutputStream(out);
  32.             DataInputStream inn = new DataInputStream(client.getInputStream());
  33.          System.out.println(inn.readUTF());
  34.             data.writeUTF("hi!server!");
  35.             data.flush();
  36.             data.close();
  37.             inn.close();
  38.             client.close();
  39.         } catch (UnknownHostException e) {
  40.             // TODO 自动生成的 catch 块
  41.             e.printStackTrace();
  42.         } catch (IOException e) {
  43.             // TODO 自动生成的 catch 块
  44.             e.printStackTrace();
  45.         }
  46.       }
  47.     }


  48. public class TCPClient1 {
  49.  
  50.      public static void main(String[] args){
  51.          
  52.          try {
  53.             @SuppressWarnings("resource")
  54.             Socket client = new Socket("127.0.0.1",11111);
  55.             OutputStream out = client.getOutputStream();
  56.             DataOutputStream data = new DataOutputStream(out);
  57.             DataInputStream inn = new DataInputStream(client.getInputStream());
  58.          System.out.println(inn.readUTF());
  59.             data.writeUTF("hi!server!");
  60.             data.flush();
  61.             data.close();
  62.             inn.close();
  63.             client.close();
  64.         } catch (UnknownHostException e) {
  65.             // TODO 自动生成的 catch 块
  66.             e.printStackTrace();
  67.         } catch (IOException e) {
  68.             // TODO 自动生成的 catch 块
  69.             e.printStackTrace();
  70.          }
  71.       }
  72.    }


下面谈谈基于UDP协议的网络通信,由于UDP通信是发送的IP数据报,无需建立连接,是一种不可靠的连接,这和TCP通信有很大的区别。

点击(此处)折叠或打开

  1. public class UDPServer {
  2.   public static void main(String[] args){
  3.      
  4.      byte b[] = new byte[1000];
  5.      DatagramPacket dp = new DatagramPacket(b, b.length);
  6.          ByteArrayOutputStream by = new ByteArrayOutputStream();
  7.          DataOutputStream byt = new DataOutputStream(by);
  8.         
  9.         try {
  10.                 DatagramSocket ds = new DatagramSocket(111); 
  11.                 ds.receive(dp);
  12.                 ByteArrayInputStream bais = new ByteArrayInputStream(b);
  13.                 DataInputStream dis = new DataInputStream(bais);
  14.                 System.out.println(dis.readUTF());
  15.                 byt.writeUTF("hi!Client!");
  16.                 byte c[] = by.toByteArray();
  17.                 DatagramPacket dpp = new DatagramPacket(c, c.length,new InetSocketAddress("127.0.0.1", 1111));
  18.                 DatagramSocket dss = new DatagramSocket();
  19.                 dss.send(dpp);
  20.                } catch (SocketException e1) {
  21.             // TODO 自动生成的 catch 块
  22.             e1.printStackTrace();
  23.         } catch (IOException e) {
  24.             // TODO 自动生成的 catch 块
  25.             e.printStackTrace();
  26.         }
  27.     }
  28. }
  29. public class UDPClient {
  30.    public static void main(String[] args){
  31.      
  32.      
  33.      ByteArrayOutputStream w = new ByteArrayOutputStream();
  34.      DataOutputStream ou = new DataOutputStream(w);
  35.      byte d[] = new byte[1000];
  36.      DatagramPacket dpp = new DatagramPacket(d, d.length);
  37.      
  38.      
  39.      try {
  40.          
  41.         DatagramSocket dss = new DatagramSocket(1111);
  42.         ou.writeUTF("hi,Server!");
  43.         byte a[] = w.toByteArray();
  44.         DatagramPacket dp = new DatagramPacket(a, a.length,new InetSocketAddress("127.0.0.1", 111));
  45.         DatagramSocket ds = new DatagramSocket();
  46.         ds.send(dp);
  47.         dss.receive(dpp);
  48.         ByteArrayInputStream bais = new ByteArrayInputStream(d);
  49.         DataInputStream dis = new DataInputStream(bais);
  50.         System.out.println(dis.readUTF());
  51.     } catch (IOException e) {
  52.         // TODO 自动生成的 catch 块
  53.         e.printStackTrace();
  54.      }
  55.    }
  56. }
以上同样是server与Client端相互通信,和TCP协议通信有很大的区别,其中有很多的细节还需要注意。虽然UDP不需要建立连接,但是在网络传送中,需要告诉它目的主机IP,以及应用程序端口号,然后经过层层的封装,然后由底层物理链路传送比特流。
以上作为个人学习总结,有很多知识没有总结到,比如URL,URI类。上文如有不当或错误之处,请读者指正!谢谢!

你可能感兴趣的:(Java网络编程)