网络编程
- URL
统一资源位置.是一种特殊的URI,除了标识一个资源,还为资源额外提供一个特定的网罗位置.
语法表示形式为:
protocol://userlnfo@host:port/path?query#fragment
协议://用户信息@主机名:端口/路径?查询#锚点
IP地址唯一标识了计算机,URL则标识了计算机上的资源
为了方便程序员编程,在JDK中提供了URL类,全名为java.net.URL, 可以使用它的各种方法来对URL对象进行处理
- 网络爬虫原理
public static void main(String[] args) throws IOException {
URL url=new URL("http://www.baidu.com");
// 主页 默认资源
//获取资源 网络流 可能会出现乱码:1、字 节数不够 2、编码解码格式不统一
/* 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("baidu2.html"),"utf-8")); String msg=null;
while((msg=br.readLine())!=null){
//将网络内容下载到本地。然后进行数据分析,建 立索引,这也是搜索引擎的第一步。
bw.append(msg);
bw.newLine();//新增方法 插入换行符
}
bw.flush();//强制刷出
//关闭通道
bw.close();
br.close(); }
- 传输层协议
*协议
TCP:面向连接,安全.可靠.效率低
UDP:非面向连接,不安全.数据可能丢失.效率高
UDP编程:DatagramSocket,DatagramPacket
是一种无连接的传输层协议,提供面向事务的简单不可靠信息传从服务.其特点为非面向连接;传输不可靠;数据可能丢失
**注意!!因为UDP的特性影响,读写速率不平等,会发生丢包现象.
解决方案:使用多线程来使传输完一遍后睡眠10毫秒来解决这种情况**
DatagramSocket:用于发送或接收数据报的数据报包:
-
当服务器要向客户端发送数据时,需要在服务器端产生
一个DatagramSocket对象,在客户端产生一个
DatagramSocket对象。服务器端的DatagramSocket将 DatagramPacket发送到网络上,然后被客户端的
DatagramSocket接收。 -
DatagramSocket有两种构造函数。一种是无需任何参数
的,常用于客户端。另一种需要指定端口,常用于服务
器。常用方法:send
,receive
,close
-
DatagramPacket:数据容器(封包)的作用:
常用方法:构造函数、getAddrress(获取发送或接收方计
算机的Ip地址)、getData(获取发送或接收的数据),
setData(设置发送的数据)
发送端
public static void main(String[] args) throws Exception {
//定义为发送端 将端口设为1999
DatagramSocket client=new DatagramSocket(1999);
System.out.println("========发送端=========");
//准备发送数据
//首先文件字节输入流
InputStream is=new BufferedInputStream(new FileInputStream("发送文件路径"));
//创建一个字节数组 用来搬运io流中传输的数据
byte [] bytes=new byte[1024*6];
int len=-1;
//将数据赋值给数组 进行存储
//小括号内填入使用的工具 用byte类型的数组来搬运
while ((len=is.read(bytes))!=-1){
//注意!!因为UDP的特性影响,读写速率不平等,会发生丢包现象,
//使用多线程来使传输完一遍后睡眠10毫秒
Thread.sleep(10);
System.out.println(len);
//把字节数组打包 输出流
//InetAddress.getLocalHost() 返回对象的原始ip地址
//构造用于发送长度的分组数据报包 length具有偏移 ioffset指定主机上到指定的端口号。
DatagramPacket dp=new DatagramPacket(bytes,0, len, InetAddress.getLocalHost(),1103);
//将封装好的包发送出去
client.send(dp);
}
client.send(new DatagramPacket("标识".getBytes(),0,"标识".getBytes().length,
InetAddress.getLocalHost(),1103));
System.out.println("发送完毕");
//传输完成后进行关闭
is.close();
client.close();
}
接收端
public static void main(String[] args) throws Exception {
//定义为接受端
DatagramSocket server=new DatagramSocket(1103);
System.out.println("==========接收端==========");
//创建输入流 创建接受数据的工具
byte [] bytes=new byte[1024*6];
DatagramPacket pd=new DatagramPacket(bytes,bytes.length);
//获取数据后将数据写入到磁盘中去
//输出流
OutputStream os=new BufferedOutputStream(new FileOutputStream
("接收文件目的地"));
//刷新
os.flush();
while (true){
//接受流
server.receive(pd);
//拆包 将传输来的数据搬走
//将数据放入到arr数组中存储
byte [] arr=pd.getData();
//将数据的长度赋值给len
int len=pd.getLength();
System.out.println("接收到的数据长度为"+len);
if ("拜拜".equals(new String(arr,0,len))){
break;
}
System.out.println("=====");
//使用输出流写入磁盘中
os.write(arr,0,len);
}
os.flush();
System.out.println("输出完成");
os.close();
server.close();
}
TCP编程:ServerSocket,Socket
-
TCP是一种面向连接,可靠的,基于字节流的传输层通信协议的点到点通信.
-
特点:
基于tcp协议,建立稳定连接的点对点的通信;实时.快速.安全性高.占用资源多.效率低;"请求-响应"模式- 客户端:
在网络通讯中,第一次主动发起通讯的程序被称作客户端 程序 - 服务器:
第一次通讯中等待连接的程序被称作服务器程序
- 客户端:
- Socket:发送TCP消息
- ServerSocket:创建服务器
套接字是一种进程间的数据交换机制
能起到通信端点的作用.单个套接字是一个断电,而一对套接字则够撑了一个双向通讯道,
使非关联进程可以在本地或通过网络进行数据交换
实际上,套接字只是计算机上已编号的端口
客户端登录,并验证
public class ClientDemo01 {
public static void main(String[] args) throws Exception {
System.out.println("---------------CLIENT----------------");
Socket client = new Socket("127.0.0.1",9876);
//用户登录
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String name = sc.nextLine();
System.out.println("请输入用户密码");
String pwd = sc.nextLine();
//输出流
DataOutputStream os = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
//输出
os.writeUTF("username="+name+"&password="+pwd);
//刷出
os.flush();
//读取响应
DataInputStream in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
//读入
String result = in.readUTF();
System.out.println(result);
//关闭
sc.close();
in.close();
os.close();
client.close();
}
}
服务器接受并进行验证
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server02 {
public static void main(String[] args) throws Exception {
System.out.println("---------------SERVER----------------");
ServerSocket server = new ServerSocket(9876);
boolean flag = true;
//阻塞式监听
while(flag){
Socket client = server.accept();
System.out.println("一个客户端连接成功.....");
//输入流
DataInputStream in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
String str = in.readUTF();
//处理字符串
String n = "这里输入标准id";
String p = "这里输入标准密码";
String s = "username="+n+"&password="+p;
//响应给客户端 输出
DataOutputStream os = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
//校验
if(s.equals(str)){
os.writeUTF("登录成功");
}else{
os.writeUTF("用户名或者密码失败");
}
//刷出
os.flush();
//关闭
os.close();
in.close();
client.close();
}
server.close();
}
}