黑马程序员----Java网络编程
2015-06-18 20:29
507 查看
——- android培训、java培训、期待与您交流! ———-
IP是互联网上的每一台计算机都有得一个唯一表示自己的标记。
IP地址使用4个8位的二进制数据表示,每8位之间使用圆点隔开,每个8位整数可以转换成一个0~255的十进制整数,因此我们一般看到的IP地址类似:192.168.1.1
分类:
IPv4:32位,分4段,0~255之间的十进制表示
IPv6:128位,分8段,0000~FFFF的十六进制数值,冒号分割。
java中InetAddress类要来表示IP地址,有两个子类:
Inet4Address(IPv4)
Inet6Address(IPv6)
常用方法
实例代码:
URL(Uniform Resource Locator)统一资源定位符,可以直接使用此类找到互联网上的资源如一个简单的网页。
一般由:协议名,资源所在主机,端口,资源名等部分组成。
常用构造方法:
URLConnection封装访问远程网络资源一般方法的类,通过它可以建立与远程服务器的连接,检查远程资源的一些属性。
Java中URLEncoder可以为传递的内容编码,而URLDecoder可以为传递的内容解码;
URLEncoder:
public static String encode(String s,String enc):使用指定的编码机制将字符串转编码成application/x-www-form-urlencoded MIME字符串;
URLDecoder:
public static String decode(String s,String enc):使用指定编码机制对application/x-www-form-urlencoded MIME字符串解码
TCP(Transmission Control Protocal)
是一种面向连接的、可靠的、基于字节流的传输层通信协议。
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元([1] MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体[1] 的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
Java中使用Socket实现TCP程序开发,使用此类可以方便的建立可靠的,双向的,持续的,点对点的通讯连接。
在Socket程序开发中,服务器端使用ServerScoket等待客户端的连接,在Java的网络程序中,每一个客户端都使用Socket对象表示。
在服务器端每次运行都要使用aceept()方法等待客户端连接,此方法执行之后服务器将进入阻塞状态,直到客户端连接之后程序才可以向下继续执行,此方法的返回类型是Socket,每一个Socket都表示每一个客户端连接对象。
Socket编程步骤:
1.建立网络连接;
2.打开连接到Socket的输入/输出流;
3.通过已打开的IO流进行读写操作;
4.关闭已打开的IO流和Socket;
示例代码:客户端和服务器端相互发送数据
客户端:
服务器端:
一个ServerSocket在一个时间段内只能为一个Socket客户端提供服务,要想同时对多个Socket提供服务可以使用多线程。
实例代码:
服务端:
客户端:
UDP(User Datagram Prptocol)
UDP协议全称是用户数据报协议 ,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。
UDP开发中使用DatagramPacket包装一条要发送的信息,之后使用DatagramSocket完成发送操作。
实例代码
客户端向服务端发送数据
客户端:
服务端:
TCP & UDP简单对比
1。基于连接与无连接 ;
2。对系统资源的要求(TCP较多,UDP少) ;
3。UDP程序结构较简单 ;
4。流模式与数据报模式 ;
5。TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证;
IP是互联网上的每一台计算机都有得一个唯一表示自己的标记。
IP地址使用4个8位的二进制数据表示,每8位之间使用圆点隔开,每个8位整数可以转换成一个0~255的十进制整数,因此我们一般看到的IP地址类似:192.168.1.1
分类:
IPv4:32位,分4段,0~255之间的十进制表示
IPv6:128位,分8段,0000~FFFF的十六进制数值,冒号分割。
java中InetAddress类要来表示IP地址,有两个子类:
Inet4Address(IPv4)
Inet6Address(IPv6)
常用方法
public static InnetAddress getByName(String host):根据主机获取对应的InetAddress对象 public static InnetAddress getLocalHost():根据本机过得InetAddress对象 public static InetAddress getByAddress(byte[] addr):根据原始Ip获得InetAddress对象 public String getHostName():得到IP地址 public boolean isReachable(int timeout):判断地址是否可以到达,同时指定超时时间
实例代码:
package xia.wt.net; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; public class InetAddressDemo { public static void main(String[] args) throws IOException { //获得百度的InetAddress InetAddress iad = InetAddress.getByName("www.baidu.com"); //获得百度的InetAddress byte[] ip = new byte[]{(byte)180,97,33,107}; InetAddress iadd = InetAddress.getByAddress(ip); //获得本地InetAddress InetAddress localiad = InetAddress.getLocalHost(); System.out.println(iad); System.out.println(iadd); System.out.println(localiad); //检测是否可以到达百度主机//如果可以获得权限,则典型实现将使用 ICMP ECHO REQUEST;否则它将试图在目标主机的端口 7 (Echo) 上建立 TCP 连接。可能此方式被百度防火墙拦截,一只显示连接不上 System.out.println(iad.isReachable(1000000)); } } /**输出结果 www.baidu.com/180.97.33.107 /180.97.33.107 TL-WR745N/192.168.1.107 false */
URL(Uniform Resource Locator)统一资源定位符,可以直接使用此类找到互联网上的资源如一个简单的网页。
一般由:协议名,资源所在主机,端口,资源名等部分组成。
常用构造方法:
URL(String spec):根据指定的地址实例化URL对象; URL(String protocol, String host, int port, String file) :实例化URL,并指定协议,主机,端口名字,资源文件 public URLConnection openConnection():得到URLConnection 对象 public final InputStream openStream():得到输入流
URLConnection封装访问远程网络资源一般方法的类,通过它可以建立与远程服务器的连接,检查远程资源的一些属性。
Java中URLEncoder可以为传递的内容编码,而URLDecoder可以为传递的内容解码;
URLEncoder:
public static String encode(String s,String enc):使用指定的编码机制将字符串转编码成application/x-www-form-urlencoded MIME字符串;
URLDecoder:
public static String decode(String s,String enc):使用指定编码机制对application/x-www-form-urlencoded MIME字符串解码
public class URLEncoderDemo { public static void main(String[] args) throws UnsupportedEncodingException { String s ="原始文字"; System.out.println(s); //将s进行utf-8编码 s = URLEncoder.encode(s, "utf-8"); System.out.println(s); //将s进行utf-8解码 s=URLDecoder.decode(s, "utf-8"); System.out.println(s); } } /**输出结果 原始文字 %E5%8E%9F%E5%A7%8B%E6%96%87%E5%AD%97 原始文字*/
TCP(Transmission Control Protocal)
是一种面向连接的、可靠的、基于字节流的传输层通信协议。
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元([1] MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体[1] 的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
Java中使用Socket实现TCP程序开发,使用此类可以方便的建立可靠的,双向的,持续的,点对点的通讯连接。
在Socket程序开发中,服务器端使用ServerScoket等待客户端的连接,在Java的网络程序中,每一个客户端都使用Socket对象表示。
在服务器端每次运行都要使用aceept()方法等待客户端连接,此方法执行之后服务器将进入阻塞状态,直到客户端连接之后程序才可以向下继续执行,此方法的返回类型是Socket,每一个Socket都表示每一个客户端连接对象。
Socket编程步骤:
1.建立网络连接;
2.打开连接到Socket的输入/输出流;
3.通过已打开的IO流进行读写操作;
4.关闭已打开的IO流和Socket;
示例代码:客户端和服务器端相互发送数据
客户端:
public class Client { public static void main(String[] args) throws UnknownHostException, IOException { //创建一个客户端对象 Socket s = new Socket(InetAddress.getLocalHost(),11260); //准备输出、输入流 OutputStream os = s.getOutputStream(); InputStream is = s.getInputStream(); //像服务器发送数据 os.write((Thread.currentThread().getName()+"客户端发来的消息").getBytes()); byte[] bs = new byte[1024]; int i = 0; i = is.read(bs); String str = new String(bs,0,i); System.out.println(str); //将接受到的数据返回给客户端 os.write(str.getBytes()); os.close(); is.close(); s.close(); } }
服务器端:
public class Servers { public static void main(String[] args) throws IOException { //创建ServerSocket对象并接受客户端发来的Socket对象 ServerSocket ss = new ServerSocket(11260); Socket s = ss.accept(); //获得输入、输出流 InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream(); //接受客户端发来的数据 byte[] bs =new byte[1024]; int i = 0; i=is.read(bs); String str = new String(bs,0,i); System.out.println(str); //像客户端送返回数据 os.write((str+"Echo").getBytes()); //再次接受客户端发来的数据 i = is.read(bs); str = new String(bs,0,i); System.out.println(str); os.write((str+"Echo").getBytes()); //通讯结束,关闭资源 os.close(); is.close(); s.close(); ss.close(); } }
一个ServerSocket在一个时间段内只能为一个Socket客户端提供服务,要想同时对多个Socket提供服务可以使用多线程。
实例代码:
服务端:
package xia.wt.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class ThreadSocketSer { public static void main(String[] args) throws IOException { //创建服务器对象 ServerSocket ss = new ServerSocket(8888); /*死循环接受客户端请求,没有客户端连接就一只阻塞主线程, 有客户端连接就将就收到的客户端交给一个新线程处理,主线程继续等待客户端*/ while(true){ //接受客户端请求或阻塞在此处 Socket s = ss.accept(); //有客户端连接就交给新线程处理 new Thread(new ThreadsServer(s)).start();; } } } class ThreadsServer implements Runnable{ private Socket s; //接受主线程传来的客户端信息 public ThreadsServer(Socket s){ this.s = s; } @Override public void run() { try (//创建输入输出流 BufferedReader bf = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter pw = new PrintWriter(s.getOutputStream(),true); ){ boolean tag = true; while(tag){ //循环接受客户端数据并应答,直到客户端发送的数据是以5结尾 String s = bf.readLine(); if(s.endsWith("4")){tag=false;} System.out.println(s); pw.println(s+"--Echo+"+Thread.currentThread().getName()); } bf.close();pw.close();s.close(); } catch (IOException e) { e.printStackTrace(); } } }
客户端:
public class ThreadSocketCli{ public static void main(String[] args) { //主线程创建5个线程,分别向服务端发送数据 for(int j =0;j<5;j++){ new Thread(new ThreadClient(),"线程"+j).start(); } } } class ThreadClient implements Runnable{ @Override public void run() { try(//创建客户端对象并创建输入输出流 Socket s = new Socket(InetAddress.getLocalHost(),8888); PrintWriter pw = new PrintWriter(s.getOutputStream(),true); BufferedReader bf= new BufferedReader(new InputStreamReader(s.getInputStream())); ) { for (int i = 0; i < 5; i++) { //向服务端发送包含请求次数的数据 pw.println(Thread.currentThread().getName()+"for"+i); //打印服务端返回的数据 System.out.println(bf.readLine()); } pw.close(); bf.close(); s.close(); } catch (IOException e) { e.printStackTrace(); } } }
UDP(User Datagram Prptocol)
UDP协议全称是用户数据报协议 ,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。
UDP开发中使用DatagramPacket包装一条要发送的信息,之后使用DatagramSocket完成发送操作。
实例代码
客户端向服务端发送数据
客户端:
public class UDPClient { public static void main(String[] args) throws IOException { //准备要发送的数据,并打包为DatagramPacket byte[] bs = "客户端发来的数据".getBytes(); DatagramPacket dp=new DatagramPacket(bs,bs.length,InetAddress.getLocalHost(),8888); //发送数据 DatagramSocket da = new DatagramSocket(8080); da.send(dp); } }
服务端:
public class UDPServer { public static void main(String[] args) throws IOException { //准备数据包,用于接受数据 byte[] bs = new byte[1024]; DatagramPacket dp =new DatagramPacket(bs,bs.length); //接受数据并打印 DatagramSocket da = new DatagramSocket(8888); da.receive(dp); System.out.println(new String(bs,0,dp.getLength())); } }
TCP & UDP简单对比
1。基于连接与无连接 ;
2。对系统资源的要求(TCP较多,UDP少) ;
3。UDP程序结构较简单 ;
4。流模式与数据报模式 ;
5。TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证;