网络编程:关注的是底层的数据传输
网页编程:数据的展示
1、基本概念
一、网络:将不同的计算机连接在一起局域网 城域网 互联网
二、地址:Ip地址确定网络上的绝对的地址位置 房子的地址
三、端口号(相当于房门):区分计算机上的软件 相当于房门两个字节0~65535 共65536个
1、 同一个协议下,端口号不能重复,不同的协议下可以重复
2、 1024以下的端口不要使用 80-->http 21-->ftp
四、资源定位 URL 统一资源定位 URI:统一资源
五、数据的传输
1、 协议:TCP和 UDP协议(重点的)
1)、TCP(transfer control protocol):必须先建立连接 先连接在通信 电话 类似于三次握手 面向连接 安全可靠 效率相对低下
2)、UDP(UserDatagramProtocol):类似于发短信 非面向连接 效率高
现在一般是将两者结合使用,底层一些不重要的数据使用UDP传输
2、 传输
1、 先封装
2、 后拆分
3、数据封装拆分
1、 InetAddress InetSocketAddress
2、 URL
3、 TCP:serverSocket(建立在服务器上) Socket(建立在客户端上)
4、 UDP: DatagramSocket DatagramPacket
1、InetAddress:封装IP及DNS
方法:
getHostAddress() 返回ip地址
getHostName() 返回域名|本机为计算机名
InetAddress.getLocalHost();//本机
InetAddress.getByName(“IP地址|域名”);
2、InetSocketAddress:封装端口
1):创建对象:
InetSocketAddress(String hostname,int port)
InetSocketAddress(InetAddress addr,intport)
2):方法:
getAdddress()
getHostName()
getPort()
<span style="font-size:18px;">package com.net.ip; import java.net.InetAddress; import java.net.UnknownHostException; /** * 没有封装端口 * @author lyy * */ public class InetDemo1 { public static void main(String[] args) throws UnknownHostException { //使用getLoaclHost方法创建InetAddress对象 InetAddress addr = InetAddress.getLocalHost(); System.out.println(addr.getHostAddress());//返回ip地址 System.out.println(addr.getHostName());//输入计算机名 //根据域名得到InetAddress对象 addr = InetAddress.getByName("www.163.com"); System.out.println(addr.getHostAddress());//返回服务器的ip地址61.163.117.65 System.out.println(addr.getHostName()); //输出 www.163.com //根据ip得到InetAddress对象 addr = InetAddress.getByName("61.163.117.65");//如果ip地址存在而且DNS帮你解析了,那么getHostName()这个方法返回的就是www.163.com ,否则输出Ip地址 System.out.println(addr.getHostAddress());//返回163的服务器的ip System.out.println(addr.getHostName());//输入Ip而不是域名,如果这个Ip地址不存在 } </span> }
<span style="font-size:18px;">package com.net.ip; import java.net.*; /** * 封装端口:在InetAddress基础上+端口 * @author lyy * */ public class InetSocketDemo1 { public static void main(String[] args) throws UnknownHostException { InetSocketAddress address = new InetSocketAddress("127.0.0.1", 9999); address= new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9999); System.out.println(address.getHostName()); System.out.println(address.getPort()); InetAddress addr = address.getAddress(); System.out.println(addr.getHostAddress());//返回ip地址 System.out.println(addr.getHostName());//输入计算机名 } }</span>
URI(Uniform resource identifier) 统一资源标识符,用唯一的标识一个资源
URL(Uniform resource Locator)统一资源定位器,他是一种具体的URI
四部分组成:协议存放资源的主机域名端口 资源文件名(/)
URL:
一、创建
URI(URL context,
String spec)//
相对路径构建
二、方法:
System.out.println("协议:"+url.getProtocol());
System.out.println("域名:"+url.getHost());
System.out.println("端口:"+url.getPort());
System.out.println("资源:"+url.getFile());
System.out.println("相对路径资源:"+url.getPath());
System.out.println("锚点:"+url.getRef());//锚点
System.out.println("参数:"+url.getQuery());//参数:存在锚点回返Null 如果不存在返回参数
<span style="font-size:18px;">package com.net.url; import java.net.*; public class URLDemo1 { public static void main(String[] args) throws MalformedURLException { //绝对路径构建 URL url = new URL("http://www.baidu.com:80/index.html#aa?uname=lyy"); System.out.println("协议:"+url.getProtocol()); System.out.println("域名:"+url.getHost()); System.out.println("端口:"+url.getPort()); System.out.println("资源:"+url.getFile()); System.out.println("相对路径资源:"+url.getPath()); System.out.println("锚点:"+url.getRef());//锚点 System.out.println("参数:"+url.getQuery());//参数 :存在锚点 返回Null 如果不存在返回参数 //相对路径构建 url = new URL("http://www.baidu.com:80/a/"); url = new URL(url,"b.txt");//相对路径 System.out.println(url.toString()); } }<strong> </strong></span>
package com.net.url; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.*; /** * 获取资源:源代码 * @author lyy * */ public class URLDemo2 { public static void main(String[] args) throws IOException { URL url = new URL("http://www.baidu.com/");//主页默认资源 //获取资源 网络流 // InputStream is = url.openStream(); // byte[] flush = new byte[1024]; // int len = 0; // while(-1 != (len = is.read(flush))){ // System.out.println(new String(flush,0,len)); // } // is.close(); BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(),"utf-8")); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("baidu.html"),"utf-8")); String msg = null; while((msg = br.readLine()) != null){ bw.append(msg); bw.newLine(); } bw.flush(); br.close(); bw.close(); } }
UDP:以数据为中心 非面向连接 不安全 数据可能丢失 效率高
一、类 DatagramSocketDatagramPacket
1、 客户端:
1)、创建客户端DatagramSocket 类 +指定端口
2)、准备数据字节数组
3)、打包 datagramPacket + 服务器地址和端口
4)、发送
5)、释放资源
2、 服务端
a) 创建服务端 DatagramSocket类 +指定端口
b) 准备接收的容器字节数组 封装datagramPacket
c) 包接收数据
d) 分析数据
e) 释放资源
典型的b/s 先从服务器下载源到浏览器(客户端)
<span style="font-size:18px;">package com.net.udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * 服务端 * 1 创建服务端 + 端口 * 2 准备接收容器 * 3 封装成包 * 4 接收数据 * 5 分析数据 * @author lyy * */ public class MyServer { public static void main(String[] args) throws IOException { // 1 创建服务端 + 端口 DatagramSocket server = new DatagramSocket(8888); // 2 准备接收容器 byte[] container = new byte[1024]; // 3 封装成包 DatagramPacket(byte[] buf, int length) DatagramPacket packet = new DatagramPacket(container, container.length); // 4 接收数据 server.receive(packet); // 5 分析数据 byte[] data = packet.getData(); int len = packet.getLength(); System.out.println(new String(data,0,len)); //释放资源 server.close(); } }</span>
<span style="font-size:18px;">package com.net.udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; /** * 客户端 * 1 创建客户端 + 端口 * 2 准备数据 * 3 打包(发送的地点 以及端口) * 4 发送 * 5 释放 * * @author lyy * */ public class MyClient { public static void main(String[] args) throws IOException { // 1 创建客户端 + 端口 DatagramSocket client = new DatagramSocket(6666); // 2 准备数据 String msg = "真的爱你"; byte[] data = msg.getBytes(); // 3 打包(发送的地点 以及端口) DatagramPacket(byte[] buf, int length, InetAddress address, int port) DatagramPacket packet = new DatagramPacket(data, data.length,new InetSocketAddress("localhost",8888)); // 4 发送 client.send(packet); // 5 释放 client.close(); } } </span>
基于TCP:面向连接安全 可靠 效率低 类似于打电话
一、面向连接:请求 响应 Request——Response
二、Socket 编程
1、服务器ServerSocket
2、客户端 Socket
package com.net.tcp.socket; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * 必须先启动服务器 后连接 * 1 创建服务器 指定端口 * 2 接收客户端连接 * 3 发送数据和接收数据 * * 接收多个客户端 * @author lyy * */ public class MultServer { public static void main(String[] args) throws IOException { //1 创建服务区 指定端口 ServerSocket(int port) ServerSocket server = new ServerSocket(8888); // 2 接收客户端连接 阻塞式 while(true){//死循环 一个accept() 一个客户端 Socket socket = server.accept(); System.out.println("一个客户端建立连接"); // 3 发送数据 String msg = "欢迎使用"; DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeUTF(msg); dos.flush(); while(true){ } } } }
package com.net.tcp.socket; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.net.UnknownHostException; /** * 1 创建客户端 必须指定服务器 + 端口 此时连接 * Socket(InetAddress host, int port) * 接收数据 发送数据 * @author lyy * */ public class Client { public static void main(String[] args) throws UnknownHostException, IOException { // 1 、创建客户端 必须指定服务器 + 端口 此时连接 Socket client = new Socket("192.168.1.112", 8888); // 2 接收数据 // BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); // String echo = br.readLine();//阻塞式的方法 // System.out.println(echo); DataInputStream dis = new DataInputStream(client.getInputStream()); String echo = dis.readUTF(); System.out.println(echo); } }
7、小案例(强烈建议大家自己敲一遍,很好玩!)
使用的多线程、流以及socket通信原理的方式,创建了一个公众聊天室的demo,进入有系统提示,可以@名字说悄悄话等等,对socket整个知识点稍微了解了更加深入一点点,还是要多消化消化,今天做了一天了,头有点大了,不说了上案例
package com.net.tcp.chat.demo4; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; /** * 创建服务器 * @author lyy * */ public class Server { private List<MyChanel> all = new ArrayList<MyChanel>(); public static void main(String[] args) throws IOException { new Server().start(); } public void start() throws IOException{ ServerSocket server = new ServerSocket(9999); while(true){ Socket client = server.accept(); MyChanel channel = new MyChanel(client); all.add(channel);//加入到容器中同意管理 new Thread(channel).start();//一条道路 } } /** * 一个客户端一个道路 * 1 输入流 * 2 输出流 * 3 接收数据 * 4 发送数据 * @author lyy * */ private class MyChanel implements Runnable{ private DataInputStream dis; private DataOutputStream dos; private boolean isRunning = true; private String name; public MyChanel(Socket client) { try { dis = new DataInputStream(client.getInputStream()); dos = new DataOutputStream(client.getOutputStream()); this.name = dis.readUTF(); this.send("欢迎你进入聊天室!"); sendOthers(this.name+"进入了聊天室",true); } catch (IOException e) { CloseUtil.closeAll(dis,dos); isRunning = false; } } /** * 读取数据 * @return */ private String receive(){ String msg = ""; try { msg = dis.readUTF(); } catch (IOException e) { CloseUtil.closeAll(dis); isRunning = false; all.remove(this);//移除自身 } return msg; } /** * 发送数据 */ public void send(String msg){ if(null == msg && !msg.equals("")){ return; } try { dos.writeUTF(msg); dos.flush(); } catch (IOException e) { // e.printStackTrace(); CloseUtil.closeAll(dos); isRunning = false; all.remove(this);//移除自身 } } /** * 发送给其他客户端 */ private void sendOthers(String msg,boolean sys){ System.out.println(msg); //是否为私聊 约定 if(msg.startsWith("@") && msg.indexOf(":") > -1){//表示私聊 String name = msg.substring(1, msg.indexOf(":")); String conetnt = msg.substring(msg.indexOf(":")+1); //获取Name for (MyChanel other : all) { if(other.name.equals(name)){ other.send(this.name+"对您悄悄说"+conetnt); } } }else{ //遍历容器 for (MyChanel other : all) { if(other == this){ continue; } if(sys){//系统信息 //发送给其他客户端 other.send("系统信息:"+msg); }else{ //发送给其他客户端 other.send(this.name+":"+msg); } } } } @Override public void run() { while(isRunning){ sendOthers(receive(),false); } } } }
package com.net.tcp.chat.demo4; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; /** * 发送数据线程 * @author lyy * */ public class Send implements Runnable{ //控制台的输入流 private BufferedReader console; //管道输出流 private DataOutputStream dos; //控制线程 private boolean isRunning = true; //名称 private String name; public Send() { console = new BufferedReader(new InputStreamReader(System.in)); } public Send(Socket client , String name){ this(); try { dos = new DataOutputStream(client.getOutputStream()); this.name = name; send(this.name); } catch (IOException e) { // e.printStackTrace(); isRunning = false; CloseUtil.closeAll(dos,console); } } //从控制台接收数据 private String getMsgFromConsole(){ try { return console.readLine(); } catch (IOException e) { e.printStackTrace(); } return ""; } /** * 从控制台接收数据 * 发送数据 */ public void send(String msg){ if(msg != null && !msg.equals("")){ try { dos.writeUTF(msg); dos.flush();//强制刷新 } catch (IOException e) { // e.printStackTrace(); isRunning = false; CloseUtil.closeAll(dos,console); } } } @Override public void run() { //线程体 while(isRunning){ send(getMsgFromConsole()); } } }
package com.net.tcp.chat.demo4; import java.io.DataInputStream; import java.io.IOException; import java.net.Socket; /** * 接收线程 * @author lyy * */ public class Receive implements Runnable{ //输入流 private DataInputStream dis; //线程标识 private boolean isRunning = true; public Receive() { } public Receive(Socket client){ try { dis = new DataInputStream(client.getInputStream()); } catch (IOException e) { // e.printStackTrace(); isRunning = false; CloseUtil.closeAll(dis); } } /** * 接收数据 * @return */ public String receive(){ String msg =""; try { msg = dis.readUTF(); } catch (IOException e) { isRunning = false; CloseUtil.closeAll(dis); } return msg; } @Override public void run() { //线程体 while(isRunning){ System.out.println(receive()); } } }
<span style="font-size:18px;">package com.net.tcp.chat.demo4; import java.io.Closeable; import java.io.IOException; /** * 关闭流的方法 * @author lyy * */ public class CloseUtil { public static void closeAll(Closeable... io){ for(Closeable temp :io){ if(null != temp){ try { temp.close(); } catch (IOException e) { e.printStackTrace(); } } } } </span> }
<span style="font-size:18px;">package com.net.tcp.chat.demo4; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.net.UnknownHostException; /** * 创建客户端 发送数据 + 接收数据 * 写出数据 输出流 * 读取数据 输入流 * @author lyy * * 输入流和输出流在同一个线程内 彼此独立 * * * */ public class Client { public static void main(String[] args) throws UnknownHostException, IOException { System.out.println("请输入名称:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String name = br.readLine(); if(name.equals("")){ return; } Socket client = new Socket("localhost", 9999); new Thread(new Send(client,name)).start();//一条路径 new Thread(new Receive(client)).start();//一条路径 } } </span>
学习了一天,感觉还是有很大的收获的,需要多消化消化,希望大家也能从中收获一点自己想要的东西,加油!
总结案例下载:http://download.csdn.net/detail/qq_14996421/9527603
java 网络编程(Socket) TCP/UDP 总结案例
原文:http://blog.csdn.net/qq_14996421/article/details/51472718