JavaSE之网络编程复习(Day26)
javaSe基础中的网络编程算是学习javaEE的选学内容。但是多学点总是没有坏处,也增加些对网络方面的了解,当然对于大学学习计算机专业的学生来说,这些基础知识就太基础了。
学习网络编程要用到IO流的知识,毕竟涉及到文件或者字符的传输!!
网络编程的学习大纲:
- 网络通讯的相关概念
- InretAddress类的使用
- 基于TCP的网络通讯: Socket 和ServerSocket 也就是套接字的使用
- 基于UDP的网络通讯: DatagramSocket 和 DatagramPacket
网络通讯的相关概念:
网络通讯:
多台计算机在网络中进行数据传输,称为网络通信
对于程序员来讲,通过一定的方法,将数据从一台设备传输到另外一台设备,或接受另外一台设备传输过来的数据。
java.net包下提供了一批类,可以实现数据在网络的传输
网络
多台计算机通过一定的物理设备连接在一起,构成了网络。
网络根据覆盖范围不同,分为
局域网:覆盖范围最小,一般指一个教室或机房
城域网:覆盖范围居中,一般指一个城市或一个企业
广域网:覆盖范围最大,一般指全国甚至全球
www万维网是广域网的代表
IP地址
这里就不要了解过多了,知道啥是ip地址就好了,(像A类 B 类 C类地址,广播地址可以不知道)
概念:用于唯一标识网络中的每台计算机
表示形式:点分十进制 xx.xx.xx.xx
每个十进制的范围:0~255
127.0.0.1 本机的回环地址,Web中经常用到
ipconfig 查看本机ip
ping检测网络是否连通
域名
概念:为了方便记忆,将ip地址一一映射成了域名
知道啥叫DNS,域名解析,将域名解析成ip地址!!!!
手机上:
通信录:
联系人姓名————联系人电话
域名—————————ip地址
www.baidu.com
www.atguigu.com
端口号(这个记住,以后经常接触)
概念:用于唯一标识某台设备上的网络程序
表示形式:0~65535
0~1024已经被占用
常见网络程序的端口号:
mysql:3306
sqlserver:1433
oracle:1521
tomcat:8080
通信协议
面向连接(安全) 速率 数据限制 需要释放连接资源
基于TCP协议 √ 低 无 √
基于UDP协议 × 高 有,64k ×
同样先记这些,虽说我学过计算机网络,知道的知识更加详细,但是学习Java网络编程知道这些就够了。
代码上手:
前奏:如果我们要进行网络的传输,那便要知道接收者的ip地址,端口号,不然不知道传送给谁。得到本机的ip地址可以通过 dos命令(windos+r打开dos窗口) 输入ipconfig
可以查看本机的IP地址,当然Java也提供了相应的类。
InetAddress类(可以去查API)
eg(列子):
public class Demo {
public static void main(String[] args) throws UnknownHostException {
InetAddress inet = InetAddress.getByName("www.baidu.com");
System.out.println(inet);
//获取inet对象所包含的域名
System.out.println(inet.getHostName());
//获取inet对象所包含的ip地址
System.out.println(inet.getHostAddress());
//获取本机地址
InetAddress inetAddress = InetAddress.getLocalHost();
System.out.println(inetAddress);
}
}
TCP、UDP、URL网络编程
这些编程都离不开Socket(有这个概念就行)
1、利用套接字(Socket)开发网络应用程序早已被广泛的采用,以至于成为事实上的标准。
2、通信的两端都要有Socket,是两台机器间通信的端点
网络通信其实就是Socket间的通信。
3、Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。
一般主动发起通信的应用程序属客户端,等待通信请求的为服务端
Socket类的常用方法
基于Socket的TCP编程
客户端Socket的工作过程包含以下四个基本的步骤:
1、创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
2、打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用 getOutputStream()方法获得输出流,进行数据传输
3、按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
3、关闭 Socket:断开客户端到服务器的连接,释放线路
服务器程序的工作过程包含以下四个基本的步骤:
调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。
关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。
客户端创建Socket对象
客户端程序可以使用Socket类创建对象,创建的同时会自动向服务器方发起连接。Socket的构造方法是:
1、Socket(String host,int port)throws UnknownHostException,IOException:向服务器(域名是host。端口号为port)发起TCP连接,若成功,则创建Socket对象,否则抛出异常。
2、Socket(InetAddress address,int port)throws IOException:根据InetAddress对象所表示的IP地址以及端口号port发起连接。
客户端建立socketAtClient对象的过程就是向服务器发出套接字连接请求
public class Demo {
//测试客户端
@Test
public void testClient() throws Exception {
//1.创建客户端套接字对象,同时指定要连接的服务端的ip和端口号
Socket socket = new Socket(InetAddress.getLocalHost(),8888);
//2.发送数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write("I am Client".getBytes());
//3.关闭
outputStream.close();
socket.close();
}
//测试服务端
@Test
public void testServer() throws IOException {
//1.创建服务端套接字对象,同时指定自己的端口号
ServerSocket ss = new ServerSocket(8888);
//2.接受客户端的连接请求
Socket socket = ss.accept();
//3.接受数据
InputStream inputStream = socket.getInputStream();
byte[] b = new byte[1024];
int len;
while((len = inputStream.read(b))!=-1) {
System.out.print(new String(b,0,len));
}
//4.关闭
inputStream.close();
socket.close();
ss.close();
}
}
TCP网络通讯
/**
* 此类用于演示基于TCP协议的网络通信
*
* 特点:面向连接的,安全可靠的,必须释放连接的
*
*
* 客户端client
*
* 服务端server
*
* 步骤:
*
* 客户端——>服务端 :发送连接请求
*
* 客户端——>服务端:发送数据
*
* 服务端——>客户端:回复数据
*
* 进阶2:客户端——>服务端,服务端接受并打印,并回复数据给客户端
*
*/
public class TestTCP2 {
//测试客户端
@Test
public void testClient() throws Exception {
//1.创建客户端套接字对象,同时指定要连接的服务端的ip和端口号
Socket socket = new Socket(InetAddress.getLocalHost(),8888);
//2.-----------------读写数据------------------------------
//2-1 发送数据(向服务端发送数据)
OutputStream outputStream = socket.getOutputStream();
outputStream.write("I am Clinet!hahah".getBytes());
socket.shutdownOutput();
//2-2 读取数据(读取服务端发来的数据)
InputStream inputStream = socket.getInputStream();
byte[] b = new byte[1024];
int len;
while((len = inputStream.read(b))!=-1) {
System.out.print(new String(b,0,len));
}
//3.关闭
inputStream.close();
outputStream.close();
socket.close();
}
//测试服务端
@Test
public void testServer() throws IOException {
//1.创建服务端套接字对象,同时指定自己的端口号
ServerSocket ss = new ServerSocket(8888);
//2.接受客户端的连接请求
Socket socket = ss.accept();
//3.-------------------读写数据--------------------------
//3-1.接受数据(读取客户端发来的数据)
InputStream inputStream = socket.getInputStream();
byte[] b = new byte[1024];
int len;
while((len = inputStream.read(b))!=-1) {
System.out.print(new String(b,0,len));
}
//3-2.发送数据(向客户端写入数据)
OutputStream outputStream = socket.getOutputStream();
outputStream.write("I am Server!xixixi".getBytes());
socket.shutdownOutput();
//4.关闭
outputStream.close();
inputStream.close();
socket.close();
ss.close();
}
}
UPD网络连接
流 程:
DatagramSocket与DatagramPacket
建立发送端,接收端
建立数据包
调用Socket的发送、接收方法
关闭Socket
发送端与接收端是两个独立的运行程序
public class Demo {
//测试发送端
@Test
public void TestSend() throws Exception {
//创建发送端的套接字对象
DatagramSocket socket = new DatagramSocket();
//创建数据包对象、
byte [] buf = "yuanmomo".getBytes();
DatagramPacket packet = new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),9999);
//放松
socket.send(packet);
//关闭
socket.close();
}
//接收端
@Test
public void TestReceive() throws Exception {
//创建接收端的套接字对象,同时指定端口号
DatagramSocket socket = new DatagramSocket(9999);
//接收数据包‘’
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf,buf.length);
//接受
socket.receive(packet);
//接受处理
System.out.println(new String(buf,0,packet.getLength()));
socket.close();
}
}
要想服务器给客户端返回信息也是一样的,就服务器当成客户端,客户端当成服务器端。
URL编程
为了表示URL,java.net 中实现了类 URL。我们可以通过下面的构造器来初始化一个 URL 对象:
public URL (String spec):通过一个表示URL地址的字符串可以构造一个URL对象。例如:URL url = new URL ("http://www. atguigu.com/");
public URL(URL context, String spec):通过基 URL 和相对 URL 构造一个 URL 对象。例如:URL downloadUrl = new URL(url, “download.html")
public URL(String protocol, String host, String file); 例如:new URL("http", "www.atguigu.com", “download. html");
public URL(String protocol, String host, int port, String file); 例如: URL gamelan = new URL("http", "www.atguigu.com", 80, “download.html");
类URL的构造方法都声明抛出非运行时异常,必须要对这一异常进行处理,通常是用 try-catch 语句进行捕获。
一个URL对象生成后,其属性是不能被改变的,但可以通过它给定的方法来获取这些属性:
public String getProtocol( ) 获取该URL的协议名
public String getHost( ) 获取该URL的主机名
public String getPort( ) 获取该URL的端口号
public String getPath( ) 获取该URL的文件路径
public String getFile( ) 获取该URL的文件名
public String getRef( ) 获取该URL在文件中的相对位置
public String getQuery( ) 获取该URL的查询名
以从网上下载一张图片保存到本地为例
public class Demo {
public static void main(String[] args) throws Exception {
//网址为百度上的一张图片
URL url = new URL("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%CD%BC%C6%AC&step_word=&hs=0&pn=14&spn=0&di=69557408910&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=3222808053%2C64414831&os=2986191801%2C2405658664&simid=3220489412%2C4000788712&adpicid=0&lpn=0&ln=508&fr=&fmq=1534660846744_R&fm=&ic=undefined&s=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=http%3A%2F%2Fs4.sinaimg.cn%2Fmiddle%2F005FqKhsgy6SPgZTKbV73%26690&fromurl=ippr_z2C%24qAzdH3FAzdH3Fri5p5_z%26e3Bks52_z%26e3Bftgw_z%26e3Bv54_z%26e3BvgAzdH3Fri5p5AzdH3Fc8ldbmbn0aAzdH3FaacFqKif2ymSP2ZTKkV0n&gsm=0&rpstart=0&rpnum=0&islist=&querylist=");
//既有数据输入又有数据输出,则考虑用Connection();
URLConnection connection = url.openConnection();
//下面就是io中文件的复制了
InputStream input = connection.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("2.jpg"));
byte [] b = new byte[1024];
int len;
while((len=input.read(b))!=-1){
fos.write(b,0,len);
}
fos.close();
input.close();
}