黑马程序员--网络编程

来源:互联网 发布:淘宝网儿童电动车 编辑:程序博客网 时间:2024/05/30 23:34

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、概述:

Java语言是在网络环境下诞生的,所以Java语言虽然不能说是对于网络编程的支持最好的语言,但是必须说是一种对于网络编程提供良好支持的语言,使用Java语言进行网络编程将是一件比较轻松的工作。和网络编程有关的基本API位于java.net包中,该包中包含了基本的网络编程实现,该包是网络编程的基础。该包中既包含基础的网络编程类,也包含封装后的专门处理WEB相关的处理类。在此只介绍基础的网络编程类,一共分为三大部分学习,第一部分是网络的基本架构、第二部分是UDP编程、第三部分是TCP编程。

二、网络的基本架构

1. ISO/OSI的参考模型共有7层,由低层至高层分别为:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。各层功能分别为:

(1)物理层

        提供建立、维护和拆除物理链路所需的机械、电气、功能和规程的特性;提供有关在传输介质上传输非结构的位流

        及物理链路故障检测指示。在这一层,数据还没有被组织,仅作为原始的位流或电气电压处理,单位是比特。

(2)数据链路层

        负责在两个相邻结点间的线路上,无差错地传送以帧为单位的数据,并进行流量控制。每一帧包括一定数量的数据

        和一些必要的控制信息。与物理层相似,数据链路层要负责建立、维持和释放数据链路的连接。在传送数据时,如

        果接收点检测到所传数据中有差错,就要通知发方重发这一帧。

(3)网络层

        为传输层实体提供端到端的交换网络数据传送功能,使得传输层摆脱路由选择、交换方式、拥挤控制等网络传输

        细节;可以为传输层实体建立、维持和拆除一条或多条通信路径;对网络传输中发生的不可恢复的差错予以报告。

        网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息——源站点和目的站点

        地址的网络地址。

(4)传输层

        为会话层实体提供透明、可靠的数据传输服务,保证端到端的数据完整性;选择网络层的最适宜的服务;提供建

        立、维护和拆除传输连接功能。传输层根据通信子网的特性,最佳的利用网络资源,为两个端系统的会话层之间提

        供建立、维护和取消传输连接的功能,并以可靠和经济的方式传输数据。在这一层,信息的传送单位是报文。

(5)会话层

        为彼此合作的表示层实体提供建立、维护和结束会话连接的功能;完成通信进程的逻辑名字与物理名字间的对应;

        提供会话管理服务。

(6)表示层

         为应用层进程提供能解释所交换信息含义的一组服务,即将欲交换的数据从适合于某一用户的抽象语法,转换为

         适合于OSI系统内部使用的传送语法,提供格式化的表示和转换数据服务。数据的压缩,解压缩,加密和解密等

         工作都由表示层负责。

(7)应用层

         提供OSI用户服务,即确定进程之间通信的性质,以满足用户需要以及提供网络与用户应用软件之间的接口服务。

简言之,各层的作用:

   物理层:在物理媒体上传输原始的数据比特流。

   数据链路层:将数据分成一个个数据帧,以数据帧为单位传输。有应有答,遇错重发。

   网络层:将数据分成一定长度的分组,将分组穿过通信子网,从信源选择路径后传到信宿。

   传输层:提供不具体网络的高效、经济、透明的端到端数据传输服务。

   会话层:进程间的对话也称为会话,会话层管理不同主机上各进程间的对话。

   表示层: 为应用层进程提供格式化的表示和转换数据服务。

   应用层:提供应用程序访问OSI环境的手段。

 

三、UDP编程

网络通讯的方式除了TCP方式以外,有一种实现的方式就是UDP方式。UDP(User Datagram Protocol),中文意思是用户数据报协议,方式类似于发短信息,是一种物美价廉的通讯方式,使用该种方式无需建立专用的虚拟连接,由于无需建立专用的连接,所以对于服务器的压力要比TCP小很多,所以也是一种常见的网络编程方式。但是使用该种方式最大的不足是传输不可靠,当然也不是说经常丢失,就像大家发短信息一样,理论上存在收不到的可能,这种可能性可能是1%,反正比较小,但是由于这种可能的存在,所以平时我们都觉得重要的事情还是打个电话吧(类似TCP方式),一般的事情才发短信息(类似UDP方式)。网络编程中也是这样,必须要求可靠传输的信息一般使用TCP方式实现,一般的数据才使用UDP方式实现。

UDP方式的网络编程也在Java语言中获得了良好的支持,由于其在传输数据的过程中不需要建立专用的连接等特点,所以在Java API中设计的实现结构和TCP方式不太一样。当然,需要使用的类还是包含在java.net包中。

首先来介绍一个基础的网络类——InetAddress类。该类的功能是代表一个IP地址,并且将IP地址和域名相关的操作方法包含在该类的内部。关于该类的使用,下面通过一个基础的代码示例演示该类的使用,代码如下:

import java.net.*;/** * 演示InetAddress类的基本使用 */public classInetAddressDemo{         public static void main(String[] args)         {                   try                   {                            //使用域名创建对象                            InetAddress inet1 =InetAddress.getByName("www.163.com");                            System.out.println(inet1);                            //使用IP创建对象                            InetAddress inet2 =InetAddress.getByName("127.0.0.1");                            System.out.println(inet2);                            //获得本机地址对象                            InetAddress inet3 =InetAddress.getLocalHost();                            System.out.println(inet3);                            //获得对象中存储的域名                            String host =inet3.getHostName();                            System.out.println("域名:" +host);                            //获得对象中存储的IP                            String ip =inet3.getHostAddress();                            System.out.println("IP:"+ ip);                   }                   catch(Exception e){}         }}


在该示例代码中,演示了InetAddress类的基本使用,并使用了该类中的几个常用方法,该代码的执行结果是:

www.163.com/220.181.28.50

/127.0.0.1

chen/192.168.1.100

域名:chen

IP:192.168.1.100

 

 

下面介绍一下UDP方式的网络编程中,客户端和服务器端的实现步骤,以及通过基础的示例演示UDP方式的网络编程在Java语言中的实现方式。

通过udp传输方式,将一段文字数据发送出去。定义一个udp发送端:

1,建立updsocket服务。

2,提供数据,并将数据封装到数据包中。

3,通过socket服务的发送功能,将数据包发出去。

4,关闭资源。

class  UdpSend{         public static void main(String[] args)throws Exception         {                   //1,创建udp服务。通过DatagramSocket对象。                   DatagramSocket ds = newDatagramSocket(8888);                    //2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, intport)                   byte[] buf = "udp ge menlai le ".getBytes();                   DatagramPacket dp =                   newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),10000);                   //3,通过socket服务,将已有的数据包发送出去。通过send方法。                   ds.send(dp);                    //4,关闭资源。                   ds.close();         }}


 

定义udp的接收端:

1,定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络应用程序定义数字标识。方便于明确哪些数据过来该应用程序可以处理。

2,定义一个数据包,因为要存储接收到的字节数据。因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。

3,通过socket服务的receive方法将收到的数据存入已定义好的数据包中。

4,通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。

5,关闭资源

class  UdpRece{         public static void main(String[] args)throws Exception         {                   //1,创建udp socket,建立端点。                   DatagramSocket ds = newDatagramSocket(10000);                   while(true)                   {                            //2,定义数据包。用于存储数据。                            byte[] buf = newbyte[1024];                            DatagramPacket dp =new DatagramPacket(buf,buf.length);                             //3,通过服务的receive方法将收到数据存入数据包中。                            ds.receive(dp);//阻塞式方法。                                              //4,通过数据包的方法获取其中的数据。                            String ip =dp.getAddress().getHostAddress();                            String data = newString(dp.getData(),0,dp.getLength());                            int port =dp.getPort();                            System.out.println(ip+"::"+data+"::"+port);                   }         }}


 

四、TCP编程

在网络通讯中,TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。而UDP方式就类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。

这两种传输方式都是实际的网络编程中进行使用,重要的数据一般使用TCP方式进行数据传输,而大量的非核心数据则都通过UDP方式进行传递,在一些程序中甚至结合使用这两种方式进行数据的传递。

tcp分客户端和服务端:

1、客户端对应的对象是Socket。

客户端,通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。

因为tcp是面向连接的。所以在建立socket服务时,就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。

2、服务端对应的对象是ServerSocket。

服务端:

1,建立服务端的socket服务。ServerSocket();并监听一个端口。

2,获取连接过来的客户端对象。通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。

3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。并打印在控制台。

4,关闭服务端。(可选)

看下面小例子:

//客户端

class  TcpClient{         public static void main(String[] args)throws Exception         {                   //创建客户端的socket服务。指定目的主机和端口                   Socket s = newSocket("192.168.1.254",10003);                   //为了发送数据,应该获取socket流中的输出流。                   OutputStream out =s.getOutputStream();                   out.write("tcp ge menlai le ".getBytes());                   s.close();         }}


//服务端

class  TcpServer{         public static void main(String[] args)throws Exception         {                   //建立服务端socket服务。并监听一个端口。                   ServerSocket ss = newServerSocket(10003);                   //通过accept方法获取连接过来的客户端对象。                   while(true)                   {                            Socket s =ss.accept();                            String ip =s.getInetAddress().getHostAddress();                            System.out.println(ip+".....connected");                            //获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。                            InputStream in =s.getInputStream();                            byte[] buf = newbyte[1024];                            int len =in.read(buf);                            System.out.println(newString(buf,0,len));                            s.close();//关闭客户端.                   }         }}


 


0 0
原创粉丝点击