2.InetAddress类 ip类 表示互联网协议 (IP) 地址。 该类没有构造函数,不能new对象, 通过方法获取对象. InetAddress getLocalHost() 返回本地主机。 InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。 知道其主机名 ,可以获取IP地址 InetAddress getAllByName(String host)在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。 知道其主机名,可以获取其所有 IP地址。 如新浪 String getHostAddress()返回 IP 地址字符串(以文本表现形式)。 String getHostName() 获取IP地址的主机名 DB 3306 Tomcat 8080 web 80 import java.net.*; class IPDemo { public static void main(String[] args) throws UnknownHostException { //获取本机ip对象。 InetAddress ip = InetAddress.getLocalHost(); //获取主机名称 System.out.println(ip.getHostName()); //获取主机的地址。 System.out.println(ip.getHostAddress()); //通过指定的字符串主机地址获取其ip对象。 InetAddress ip2 = InetAddress.getByName("192.168.1.249"); System.out.println(ip2.getHostName()); System.out.println(ip2.getHostAddress()); } } 3.UDP 特点: 面向无连接,不可靠,速度快 1.传送时不会因接收是否存在,而不传送;接收着存在,则接收。若不在,就会数据丢失。 2.不可靠,可能会出现数据的不完整性。 3.传送速度快,效率高 作用: 将数据封装成一个“数据包”,每个数据包的大小为64K,若数据大则拆分成对个包。 应用: 聊天工具 (数据接收着不存在,其数据丢失不会有影响),视频工具(数据丢失一点并不会导致无法视频) Socket(套接字):网络传输一种机制,两个Socket之间传输IO流。 发送 : 1.创建Socket服务 DatagramSocket类建立 (任意端口号) 2.将传送数据转化为byte[] ,普通字符使用getBytes()方法 ,并将该数据封装入DatagramPacket包中 (arr,arr.length,InetAddress.getByName("192.168.1.235"),65535) 3.发送数据 通过DatagramSocket对象进行 send() 4,关闭资源。 接收: 1.创建Socket服务 DatagramSockte,并对于发送的端口号进行监听。 2.建立一个byte[], 准备放置 数据包dp的数据,建立数据包,并将数据从数据包中放置到数组中 DatagramPacket(arr,arr.length) 3.接收数据 通过DatagramSocket对象进行 ds.receive(dp),将接收的数据封装到dp数据包中。 4.通过DatagramPacket的方法获取其信息。 5.关闭资源。 使用多线程时,将建立 DatagramSocket对象放置在主函数中 在run()中try异常时,将关闭资源放置在 try外。 import java.net.*; class SendDemo { public static void main(String[] args) throws Exception { //创建udpsocket服务。 DatagramSocket ds = new DatagramSocket(); byte[] buf = "hi,ge men 坐着 UDP 来了".getBytes(); //将数据封装成数据包。 DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10000); //使用socket服务的send方法。将数据发出。 ds.send(dp); //关闭服务。 ds.close(); } } class ReceDemo { public static void main(String[] args) throws Exception { //建立udpsocket服务,监听一个10000端口,也就是凡是发到该主机10000端口的数据, //都由该应用程序所接收,并解析。 DatagramSocket ds = new DatagramSocket(10000); //通过该服务接收10000端口来数据。 //首先要建立一个数据包,用户存储接收到的数据。 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); ds.receive(dp);//将数据存储到数据包中。该方法是阻塞式方法。 String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String text = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+":"+port+"..."+text); //关闭服务。 ds.close(); } } import java.net.*; import java.io.*; class SendDemo { public static void main(String args[]) throws Exception { DatagramSocket ds=new DatagramSocket(); BufferedReader buf=new BufferedReader(new InputStreamReader(System.in)); String line=null; while((line=buf.readLine())!=null) { byte[] arr=line.getBytes(); //将读取的数据进行转换为字节数组。 DatagramPacket dp= new DatagramPacket(arr,arr.length,InetAddress.getByName("192.168.1.235"),6553); ds.send(dp); if("over".equals(line)) break; } ds.close(); } } class RecDemo { public static void main(String args[]) throws Exception { DatagramSocket ds2=new DatagramSocket(6553); while(true) //使其一直处在接收状态 ,不然就可能会数据丢失。 //{ byte[] brr=new byte[1024]; DatagramPacket dp2=new DatagramPacket(brr,brr.length); ds2.receive(dp2); //该方法是 阻塞方法 String ip=dp2.getAddress().getHostAddress(); int port=dp2.getPort(); String text=new String (dp2.getData(),0,dp2.getLength()); System.out.println(ip+"::"+port+"...."+text); } } } 应用 实现多线程下的聊天 class Send implements Runnable { private DatagramSocket ds; Send(DatagramSocket ds) //初始化对象就能产生 DatagramSocket 对象的引用 { this.ds = ds; } public void run() { try { BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line=bufr.readLine())!=null) { byte[] buf = line.getBytes() ; DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10001); ds.send(dp); if("886".equals(line)) break; } bufr.close(); ds.close(); } catch (Exception e) { } } } class Rece implements Runnable { private DatagramSocket ds; Rece(DatagramSocket ds) { this.ds = ds; } public void run() { while(true) { try { byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); ds.receive(dp); String ip = dp.getAddress().getHostAddress(); String text = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+"::"+text); } catch (Exception e) { } } } } class ChatDemo { public static void main(String[] args) throws Exception { DatagramSocket send = new DatagramSocket(); DatagramSocket rece = new DatagramSocket(10001); new Thread(new Send(send)).start(); new Thread(new Rece(rece)).start(); } } 4.TCP 特点: 面向连接 可靠,效率略低 1.数据传送时,必须要有传输者和接收者的连接。三次握手连接(1.传输者--接收者 2,接收者--传输者回应 3,传输者确认) 2.保证传送接收两者都在,数据传送安全可靠 3,需要连接,效率略低 应用: 文件下载,上传 如: 打电话。 TCP 应用特点: client :不需要循环,单一 1.使用Socket类创建 其对象 ,并通过构造函数对其指定服务器的 ip和端口 2.(源:文件)读入的类容, 写入到 目的(输出流)---------server读取 (对象socket输入流)中的数据然后服务器读取数据。在输出流把数据写入文件 OK后 server写入一句提示 给 对象的 输出流中 cilent将读取输入流中类容,并打印。 client :Socket (Send) 构造函数 Socket(String ip,int port) 通常可以在建立客户端对象,指定服务端的地址和端口 如果没有指定,可以通过方法,connect进行指定目的连接。 如果连接成功后就可以通信,若没有联通则会报异常。 连接成功就有会有Socket流 server: serverSocket (receive) Socket s.InputStream() Socket输入流 s.OutputStream() Socket输出流 ServerSocket ss = new ServerSocket(10005); Socket s = ss.accept(); 侦听并接受到此套接字的连接。 监听到Socket 访问是,产生对应的s。 //读操作 使用了Buffered 则使用Buffered的内部数组。 没有使用则必须建立自己的 字节数组 TCP中客户端的代码 import java.io.*; import java.net.*; /* 通过客户端将一个文件数据,传输到服务端。 服务端将数据保存后,回馈给客户端信息,收到。或者上传成功。 局域网网络 192.168.1.0~192.168.1.255 192.168.1.0 : 网段地址 192.168.1.255: 广播地址 ,可以用于群发消息 (有的server现在容易把该地址端口 禁用掉) 其实就是一个文件上传。 */ class UploadClient { public static void main(String[] args) throws Exception { Socket s = new Socket("192.168.1.249",10005); //指定服务器的IP 和端口 BufferedReader bufr = new BufferedReader(new FileReader("UDPDemo.java"));// 输入流的源是 文件 PrintWriter out =new PrintWriter(s.getOutputStream(),true); //输出流的目的 输出流 String line = null; while((line=bufr.readLine())!=null) { out.println(line); //将读入的数据写入到 输出流中 } s.shutdownOutput(); //给流加上一个结束标识,让对方的读取流可以结束。//只有TCP Socket类有该方法 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); //输入流的源是 输入流 String str = bufIn.readLine(); // 读取 输入流中的数据 其一行数据,不需要循环。 System.out.println(str); //打印其读取的数据。 bufr.close(); s.close(); } } //TCP 服务器的代码 import java.io.*; import java.net.*; //多用户上传文件的服务端。 //需要把每一个获取到的客户端对象封装到线程中。 class User implements Runnable { private Socket s; User(Socket s) { this.s = s; } public void run() { try { String ip = s.getInetAddress().getHostAddress(); //System.out.println(ip+".....connected"); 用于显示与那个IP建立连接 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter pw = new PrintWriter(new FileWriter(ip+".txt"),true); //自动刷新 String line = null; while((line=bufIn.readLine())!=null) { pw.println(line); } PrintWriter out = new PrintWriter(s.getOutputStream(),true); out.println("上传成功"); pw.close(); s.close(); } catch (Exception e) { } } } class UploadServer { public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(10005); while(true) // 必须的循环开启,否则就会接收不到数据 (TCP是面向连接的,在发送方必须要,接收方有连接时,才会发送数据) { Socket s = ss.accept(); //可以返回client对应的Socket , 有一个客户端访问则将该客户端封装到线程中去,实现多线程的概念 //accept是阻塞式方法,没有客户端发送数据过来,是不会产生新的Socket对象 new Thread(new User(s)).start(); } //ss.close(); } } TCP应用 (IE)浏览器的原理: 浏览器向Web服务器发送 请求数据公共数据 通过 将其数据写入Socket输出流中。 Wbe服务软件 通过ServerSocket中的accept() 返回对应的Socket对象,在Socket输入流中读取其数据,判断ok后, 通过 对有效数据(网站类容),将其数据写入到Socket对象输出流中,返回给浏览器中,浏览器读取Socket对象的输入流的 数据,并通过浏览器的解析引擎对数据解析(javascript引擎,css引擎...),处理后并显示。 //浏览器向服务器发送相关 规格数据 GET /myweb/1.html HTTP/1.1 客户端 请求资源,及客户端的HTTP版本 1.请求行 Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, i mage/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application /msword, application/QVOD, application/QVOD, //表示客户端可以应用以上的文件 2.http的请求消息头 Accept-Language: zh-cn,zu;q=0.7,vi;q=0.3 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0 .50727; staticlogin:product=cboxf2010&act=login&info=ZmlsZW5hbWU9UG93ZXJXb3JkMjA xME94Zl9VbHRpbWF0ZS5leGUmbWFjPUI5NDMzOTJDM0M1RDQxRDg4NjcyRTZFOUQ3NDdGREFEJnBhc3N wb3J0PSZ2ZXJzaW9uPTIwMTAuNi4zLjYuMiZjcmFzaHR5cGU9MQ==&verify=a9c10c91d66ac6ba2a5 cf6c3ac2db7c9; CIBA) Host: 192.168.1.249:9090 Connection: Keep-Alive //空号 表示结束标记 请求体 服务端的应答 Http/1.1 200 ok 应答行 200 表示连接 404 表示连接失败 应答消息头 应答体(回复数据给客户端) 5.URL: 类 URL 代表一个统一资源定位符 主要用于网页client与server通信 getProtocol(); getHost(): getPort(); getPath(): getFile(): getPath()+getQuery(); getQuery(); URLConnection openConnection():可以获取连接该url地址的连接对象。 在通过该对象获取socket流。对数据进行操作。 InputStream openStream(): openConnection().getInputStream(); class URLDemo { public static void main(String[] args) throws Exception { String str = "http://192.168.1.249:8080/myweb/1.html"; //将url字符串路径封装成URL对象。 URL url = new URL(str); // System.out.println("getProtocol:"+url.getProtocol()); // System.out.println("getHost:"+url.getHost()); // System.out.println("getPort:"+url.getPort()); // System.out.println("getPath:"+url.getPath()); // System.out.println("getFile:"+url.getFile()); // System.out.println("getQuery:"+url.getQuery()); URLConnection conn = url.openConnection();//打开该url的连接。就是连接到指定的目的去。 InputStream in = conn.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf,0,len)); } }