1、Java网络编程,学习目标,理解网络编程概念 掌握TCP编程 掌握UDP编程 掌握多线程网络编程,TCP/IP(Transmission Control Protocol传输控制协议/Internet Protocol网间协议)是Internet的主要协议,定义了计算机和外设进行通信所使用的规则。TCP/IP网络参考模型包括五个层次:应用层、传输层、网络层、链路层、物理层。ISO/OSI网络参考模型则包括七个层次:应用层、表示层、会话层、传输层、网络层、链路层、物理层。,物理层,网络基本概念,网络基本概念,大多数基于Internet的应用程序被看作TCP/IP网络的最上层应用层, 如:ftp,
2、http,smtp,pop3,telnet,nntp等。 网络层对TCP/IP网络中的硬件资源进行标识。连接到TCP/IP网络中的每台计算机(或其他设备)都有唯一的地址,这就是IP地址。IP地址实质上是一个32位的整数,通常以“%d.%d.%d.%d”的形式表示,每个d是一个8位整数。 在TCP/IP网络中,不同的机器之间进行通信时,数据的传输是由传输层控制的,这包括数据要发往的目标机器及应用程序、数据的质量控制等。 TCP/IP网络中最常用的传输协议就是TCP(Transport Control Protocol)和UDP(User Datagram Protocol)。,网络基本概念,一台
3、机器通常只通过一条链路连接到网络上,即它只有一个IP地址,但一台机器中往往有很多应用程序需要进行网络通信,如何区分呢?这就要靠网络端口号(port)了。 端口号是一个标记机器的逻辑通信信道的正整数,端口号不是物理实体。IP地址和端口号组成了所谓的Socket,Socket是网络上运行的程序之间双向通信链路的最后终结点,它是TCP和UDP的基础。,一台机器通常只通过一条链路连接到网络上,即它只有一个IP地址,但一台机器中往往有很多应用程序需要进行网络通信,如何区分呢?这就要靠网络端口号(port)了。端口号是一个标记机器的逻辑通信信道的正整数,端口号不是物理实体。IP地址和端口号组成了所谓的So
4、cket,Socket是网络上运行的程序之间双向通信链路的最后终结点,它是TCP和UDP的基础。,IP与端口号组合而得出的Socket,可以完全分辨Internet上运行的程序。,网络基本概念,网络基本概念,端口号是用整数来表达的,其范围为065535,其中01023为系统所保留,专门给那些通用的服务(well-known services),如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口为23,因此,当我们编写通信程序时,应选择一个大于1023的数作为端口号,以免发生冲突。,网络基本概念,传输层通常以TCP和UDP协议来控制端点到端点的通信。用于通信的端点是由
5、Socket来定义的,Socket是由IP地址和端口号组成的。传输控制协议(TCP)是在端点与端点之间建立持续的连接而进行通信。建立连接后,发送端将发送的数据印记了序列号和错误检测代码,并以字节流的方式发送出去;接收端则对数据进行错误检查并按序列顺序将数据整理好,数据在需要时可以重新发送,因此整个字节流到达接收端时完好无缺。这与两个人打电话的情形是相似的。TCP协议具有可靠性和有序性,并且以字节流的方式发送数据,它通常被称为流通信协议。,网络基本概念,与TCP协议不同,用户数据报协议(UDP)则是一种无连接的传输协议。利用UDP协议进行数据传输时,首先需要将要传输的数据定义成数据报(Datag
6、ram),在数据报中指明数据所要达到的端点(Socket,主机地址和端口号),然后再将数据报发送出去。这种传输方式是无序的,也不能确保绝对的安全可靠,但它很简单也具有比较高的效率,这与通过邮局发送邮件的情形非常相似。,网络基本概念,包中的主要的类和可能产生的例外包括:面向IP层的类:InetAddress (Inet4Address,Inet6Address) 面向应用层的类:URL、URLConnection 面向网络层的类: TCP协议相关类:Socket、ServerSocket UDP协议相关类:DatagramPacket、DatagramSocket、MulticastSocket
7、 可能产生的例外: BindException、ConnectException、MalformedURLException、NoRouteToHostException、ProtocolException、SocketException、UnknownHostException、UnknownServiceException,Socket通信,在Java中,基于TCP协议实现网络通信的类有两个:在客户端的Socket类和在服务器端的ServerSocket类。在服务器端通过指定一个用来等待的连接的端口号创建一个 ServerSocket实例。在客户端通过规定一个主机和端口号创建一个 Sock
8、et实例,连到服务器上。ServerSocket类的accept方法使服务器处于阻塞状态,等待用户请求。,构造方法: public Socket(String host, int port) /远程服务器IP及响应端口 public Socket(InetAddress address, int port) public Socket(String host, int port, InetAddress localAddr, int localPort) public Socket(InetAddress address, int port, InetAddress localAddr, in
9、t localPort) /在指定的机器上的指定端口上运行 这些方法都将抛出例外IOException,程序中需要捕获处理。,Socket通信,Socket的输入/输出流管理 public InputStream getInputStream() public void shutdownInput() public OutputStream getOutputStream() public void shutdownOutput()这些方法都将抛出例外IOException,程序中需要捕获处理。关闭Socket public void close() throws IOException设置/
10、获取Socket数据 public InetAddress getInetAddress()、public int getPort(), public void setSoTimeout(int timeout),这些方法都将抛出例外SocketException,程序中需要捕获处理。,Socket通信类ServerSocket,构造方法: public ServerSocket(int port) public ServerSocket(int port, int backlog) /支持指定数目的连接 public ServerSocket(int port, int backlog, I
11、netAddress bindAddr)/在指定的机器上运行这些方法都将抛出例外IOException,程序中需要捕获处理主要方法 public Socket accept():等待客户端的连接 public void close():关闭Socket设置/获取Socket数据 public InetAddress getInetAddress()、public int getLocalPort(), public void setSoTimeout(int timeout),这些方法都将抛出例外SocketException,程序中需要捕获处理。,Socket通信,无论一个Socket通信程
12、序的功能多么齐全、程序多么复杂,其基本结构都是一样的,都包括以下四个基本步骤:1、在客户方和服务器方创建Socket/ServerSocket实例。 2、打开连接到Socket的输入/输出流。 3、利用输入/输出流,按照一定的协议对Socket进行读/写操作。 4、关闭输入/输出流和Socket。通常,程序员的主要工作是针对所要完成的功能在第3步进行编程,第1、2、4步对所有的通信程序来说几乎都是一样的。,Socket通信,Socket通信,在本地机器上测试网络程序Socket socket = new Socket(“127.0.0.1”, 4444);建立socket连接后,还应该建立输入
13、输出数据流。要控制好输入/输出流和Socket关闭的时间。如果网络的一端已经关闭,另一端读到null。在运行时,服务器端程序一般应先行启动。,Socket通信,如何支持多客户端? 将服务器写成多线程的,不同的处理线程为不同的客户服务。主线程只负责循环等待,处理线程负责网络连接,接收客户输入的信息。,Server,client1,client2,serverthread2,serverthread1,数据报通信(UDP),UDP协议是无连接的协议,它以数据报作为数据传输的载体。数据报是一个在网络上发送的独立信息,它的到达、到达时间以及内容本身等都不能得到保证。数据报的大小是受限制的,每个数据报的
14、大小限定在64KB以内。UDP协议无需在发送方和接收方建立连接,但也可以先建立连接。数据报在网上可以以任何可能的路径传往目的地。在Java中,基于UDP协议实现网络通信的类有三个:用于表达通信数据的数据报类DatagramPacket用于进行端到端通信的类DatagramSocket用于广播通信的类MulticastSocket。,点到点通信:类DatagramSocket,构造方法 public DatagramSocket() public DatagramSocket(int port) /在指定的端口通信 public DatagramSocket(int port, InetAddr
15、ess laddr) /在指定的地点运行 这三个方法都将抛出例外SocketException,程序中需要捕获处理。最主要的方法发送与接收数据报 public void receive(DatagramPacket p) public void send(DatagramPacket p) 这两个方法都将抛出例外IOException,程序中需要捕获处理。其他方法 public void connect(InetAddress address, int port) /与指定的机器通信,有连接 public void disconnect() /关闭与指定机器的连接 public void cl
16、ose() /关闭Socket,点到点通信,发送端(服务器端)发出数据报的标准步骤: 1. 定义数据成员DatagramSocket socket;DatagramPacket packet;InetAddress address;(用来存放接收方的地址)int port; (用来存放接收方的端口号) 2. 创建数据报Socket对象trysocket = new DatagramSocket(2876);catch(.SocketException e) socket 绑定到一个本地的可用端口,等待接收客户端的请求。,数据报:类DatagramPacket,构造方法 public Datag
17、ramPacket(byte buf, int length) public DatagramPacket(byte buf, int offset, int length)/这两个方法用于描述接收数据报 public DatagramPacket(byte buf, int length, InetAddress address, int port) public DatagramPacket(byte buf, int offset, int length, InetAddress address, int port)/这两个方法用于发送数据报获取数据获取接收数据报中的信息 public
18、InetAddress getAddress() public byte getData() public int getLength() public int getOffset() public int getPort() 设置数据设置发送数据报中的信息 setAddress(InetAddress iaddr)、setPort(int iport)、setData(byte buf)、setData(byte buf, int offset, int length) 、setLength(int length),点到点通信,3.分配并填写数据缓冲区(一个字节类型的数组)byte buf
19、= new byte256; 存放从客户端接收的请求信息。 4.创建一个接收数据报DatagramPacketpacket = new DatagramPacket(buf, 256);用来从socket接收数据,它只需要两个参数5. 服务器阻塞(等待接收数据)socket.receive(packet);在客户的请求数据报到来之前一直等待。,点到点通信,从到来的接收数据报中得到客户端的地址和端口号 InetAddress address = packet.getAddress();int port = packet.getPort(); 7. 准备需要发送的数据:将数据送入缓冲区buf 或来
20、自文件、或键盘输入 8. 建立发送数据报,用来从socket向客户端发送信息packet = new DatagramPacket(buf, buf.length, address, port); 9. 发送数据包socket.send(packet); 10.关闭socketsocket.close();,点到点通信,接收端(客户端)接收数据报的标准步骤: 1. 定义数据成员int port; InetAddress address;DatagramSocket socket;DatagramPacket packet;byte sendBuf = new byte256; 2. 建立soc
21、ketsocket = new DatagramSocket();无须指定端口号,它会自动获得一个可用的端口号。,点到点通信,3. 向服务器端发出请求数据报(发送数据报)address = InetAddress.getByName(“localhost”);port = 2876;/获得服务器端的IP和端口号packet = new DatagramPacket(sendBuf, 256, address, port);socket.send(packet);这个数据报本身会带有客户端的信息 4. 客户端等待服务器端的应答(通过接收数据报接收数据)packet=new DatagramPacket(sendBuf, 256);socket.receive(packet);如果没有到就一直等待,因此实用程序要设置等待时间限度 5. 处理接收到的数据String received=new String(packet.getData(), 0);System.out.println(received);,multicast,