java 网络编程(Socket) TCP/UDP 总结案例

来源:互联网 发布:数据库认证工程师 编辑:程序博客网 时间:2024/06/05 06:16

网络编程:关注的是底层的数据传输

网页编程:数据的展示



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.65System.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的服务器的ipSystem.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>


3、网络爬虫原理

URI(Uniform resource identifier) 统一资源标识符,用唯一的标识一个资源

URL(Uniform resource Locator)统一资源定位器,他是一种具体的URI

四部分组成:协议存放资源的主机域名端口 资源文件名(/)

 URL:

一、创建

URI(String str)//绝对路径构建

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>




4、通过流读取数据——OpenStream()


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();}}


5、UDP通信

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>



6、Scoket通信

基于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);//获取Namefor (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);}}}}@Overridepublic 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);}}}@Overridepublic 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;}@Overridepublic 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

2 0
原创粉丝点击