internet概述
internet结构
- 数据链路层,物理层:统称为物理层
- 网络层:Internet协议规范
- 传输层:TCP与UDP协议规范
- 应用层,显示层,回话层:统称为应用层,指应用程序一端
IP地址和端口号
- 189.23.50.126:服务器的IP地址,是服务器的唯一标识码
- 9960:端口号,服务器部署到网络中的某一个应用程序的唯一识别码,通过端口号访问到唯一的应用程序
TCP、UDP协议
- TCP(Transmission Control Protocol):传输控制协议
- TCP传输协议是面向连接的,传输数据是最为安全的,确保数据一定会发送到目标位置,但是速度较慢
- UDP(User Datagram Protocol):用户数据报协议
- UDP是面向断开式连接的通信协议,不确保数据一定会发送到目标位置,但是速度较快
java.net组件包
- java.net.URL:统一资源定位符
- java.net.InetAddress:互联网IP地址
- java.net.Socket:客户端套接字,基于TCP
- java.net.ServerSocket:服务器套接字,基于TCP
- java.net.DatagramPacket:数据报包,基于UDP
- java.net.DatagramSoket:数据报包套接字,基于UDP
URL
URL概述
URL类代表一个统一资源定位符,指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,如对数据库或搜索引擎的查询、更改操作
url构成
http:传输协议
www.baidu.com:域名,实际就指向ip地址和端口号
index.jsp:请求的资源名称,如此处为请求jsp界面
URL构造器
- public URL(String spec)throws MalformedURLException:以字符串spec创建一个URL对像
- public URL(String protocol,String host,String file)throws MalformedURLException:以protocol代表的协议,host代表的服务器,默认端口号,file代表的文件创建一个URL对象
- public URL(String protocol,String host,int port,String file)throws MalformedURLException:以protocol代表的协议,host代表的服务器,port代表端口号,file代表的文件创建一个URL对象
- pulbic URL(URL context,String spec)throws MalformedURLException:基于URL对象context,以spec为相对路径建立一个URL对象
/***
* @date 2020/8/17
* @author Vbird
*
*/
public class URLTest {
public static void main(String[] args) {
try {
URL url = new URL("http://www.baidu.com");
URL url2 = new URL("http","localhost",9090,"pyhon.jpg");
URL url3 = new URL(url,"index.html");
url3.getFile();//获取文件
url.getProtocol();//获取协议
url2.getHost();//获取服务器名称
} catch (MalformedURLException e) {//URL命名规范的异常
e.printStackTrace();
}
}
}
InetAddress/SocketAddress
- 此类表示互联网协议(IP)地址
- IP地址 是IP使用的32位或128位无符号数字,它是一种低级协议,UDP和TCP协议都是在它的基础上构建的
- InetAddress:Ipv4,Ipv6
- SocketAddress:InetSoketAddress
- 不能单独使用,没有交互时没有实际意义
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
/***
* @date 2020/8/17
* @author Vbird
* */
public class InetAddressTest {
public static void main(String []args) {
try {
InetAddress add = InetAddress.getLocalHost();//获取本机IP
add.getHostName();//获取本机名称
add.getHostAddress();//获取本机IP地址
InetAddress baidu = InetAddress.getByName("www.baidu.com");//通过名称获取IP
baidu.getHostName();//获取baidu名称
baidu.getHostAddress();//获取baiduIP地址
} catch (UnknownHostException e) {
e.printStackTrace();
}
/*创建基于端口号的套接字IP地址实例*/
InetSocketAddress isa = new InetSocketAddress("localhost",9090);//根据主机名和端口号创建套接字地址
isa.getHostName();//获取主机名
isa.getHostString();//获取主机名字符串形式
isa.getAddress().getHostAddress();//获取主机IP地址
}
}
Socket
Socket概述
- Socket类实现客户端套接字(简称“套接字”),套接字是两台机器间通信的端点
- java基于互联网的C/S模式的客户端程序主要依赖此类实现与服务器端的通信,它是java网络编程的核心组件
- Socket组件实例通常必须绑定IP地址(客户机网络域名)和一个未被本地机器占用的端口号
Socket构造器
- public Socket():创建未连接的套接字
- public Socket(InetAddress address,int port):创建指定IP地址和端口号的套接字
- public Socket(InetAddress address,int port,InetAddress localAddr,int localPort):创建连接到远处服务器的套接字,参数有本地和远处的IP地址和端口
- public Socket(String host,int host):创建一个流套接字并将其连接到指定主机上的指定端口号
/***
* @date
* @author Vbird
*
*/
public class SocketTest {
public static void main(String[] args) {
Socket client = null;//客户端套接字
client = new Socket();//创建一个未连接的套接字
try {
Socket client2 = new Socket(InetAddress.getByName("www.baidu.com"), 9090);//通过一个指定ip地址和端口号创建一个套接字
Socket client3 = new Socket(InetAddress.getLocalHost(),9090,
InetAddress.getByName("www.baidu.com"), 9090);//创建本地连接到远处服务器的套接字
Socket client4 = new Socket("localhost",9090);//创建连接到指定主机上的端口号
}catch (IOException e1) {
e1.printStackTrace();
}
}
}
Socket常用实例实例方法
- void bind(SocketAdress bindpoint):将套接字绑定到本地地址
- void close():关闭套接字
- void connect(SocketAddress endpoint):将套接字连接到服务器 ,默认超时时间
- vooid connect(SocketAddress endpoing,int timeout):将套接字连接到服务器并指定超时时间
- InputStream getInputStream():返回此套接字的输入流
- OutputStream getOutputStream():返回此套接字的输出流
/***
* @date
* @author Vbird
*
*/
public class ClientSocket {
public static void main(String[] args) {
Socket client = null;//客户端套接字
client = new Socket();//创建一个未连接的套接字
/*创建一个本地套接字地址及端口对象*/
SocketAddress localAddress = new InetSocketAddress("localhost",9090);
/*创建一个远处套接字地址及端口对象*/
SocketAddress removeAddress = new InetSocketAddress("localhost",9898);
InputStream in = null;//声明一个输入流
OutputStream out = null;//声明一个输出流
DataInputStream din = null;//创建用于传输数据的输入流
DataOutputStream dout = null;//创建用于传输对象的输出流
try {
/*将套接字绑定到本地地址及端口*/
client.bind(localAddress);
client.isBound();//判断套接字是否绑定
/*尝试连接到远处的服务器*/
client.connect(removeAddress);
din = new DataInputStream(in);//基于in创建数据输入流
dout = new DataOutputStream(out);//基于out创建数据输出流
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
/*在不需要套接字实例时,通常必须关闭套接字(首先关闭基于套接字建立的输入和输出流)
*通过socket.shutdownOutput/Input()关闭输入输出流,连接会保持
*通过in/out.close()会直接关闭socket
* */
client.shutdownInput();
client.shutdownOutput();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ServerSocket
SeverSocket概述
ServerSocket类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
ServerSocket构造器
- public ServerSocket()throws IOException:创建非绑定服务器套接字
- public ServerSocket(int port):创建绑定到特定端口的服务器套接字
- public ServerSocket(int port,int backlog):创建指定端口号和队列长度的服务器套接字
- public ServerSocket(int port,int backlog,InetAddress bindAddr):指定端口号队列长度及主机地址创建套接字
/***
* @date 2020/8/17
* @author Vbird
*
*/
public class Server {
public static void main(String[] args) {
try {
/*创建非绑定服务器套接字*/
ServerSocket server = new ServerSocket();
/*创建服务器套接字并绑定到9898端口*/
ServerSocket server2 = new ServerSocket(9898);
} catch (IOException e) {
e.printStackTrace();
}
}
}
ServerSocket常用实例方法
- public Socket accept()throws IOException:侦听并接受到此套接字的连接,未连接前处于阻塞状态
- void close():关闭套接字
- public void setSoTimeout(int timeout):以毫秒为单位设置超时时间如果为0则永不超时
- public boolean isBound():测试ServerSocket是否绑定
- public boolean isClosed():测试ServerSocket是否关闭
- public InterAddress getInetAddress():返回此服务器套接字的本地地址
/***
* @date 2020/8/17
* @author Vbird
*
*/
public class Server {
public static void main(String[] args) {
ServerSocket server = null;//创建服务器套接字
InputStream in = null;//声明一个输入流
OutputStream out = null;//声明一个输出流
DataInputStream din = null;//创建用于传输数据的输入流
DataOutputStream dout = null;//创建用于传输数据的输出流
try {
/*创建非绑定服务器套接字*/
server = new ServerSocket();
/*将server服务器套接字绑定到本地地址9898端口*/
server.bind(new InetSocketAddress("localhost",9898));
/*测试服务器套接字是否绑定*/
server.isBound();
din = new DataInputStream(in);//基于in创建数据输入流
dout = new DataOutputStream(out);//基于out创建数据输出流
while(true){//循环等待客户端连接
System.out.println("等待连接......");
/*服务器接收连接请求
*在接收到请求之前,处于线程阻塞状态,后方代码将不会运行,与控制台输入时未接收到输入数据相同
* */
server.accept();
System.out.println("连接成功");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
/*关闭服务器套接字*/
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务器与客户端交互(同一机器两个eclipse下运行)
客户端
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Scanner;
/***
* @date
* @author Vbird
*
*/
public class ClientSocket {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Socket client = null;//客户端套接字
client = new Socket();//创建一个未连接的套接字
/*创建一个本地套接字地址及端口对象*/
SocketAddress localAddress = new InetSocketAddress("localhost",9090);
/*创建一个远处套接字地址及端口对象*/
SocketAddress removeAddress = new InetSocketAddress("localhost",9898);
InputStream in = null;//声明一个输入流
OutputStream out = null;//声明一个输出流
DataInputStream din = null;//创建用于传输数据的输入流
DataOutputStream dout = null;//创建用于传输数据的输出流
try {
/*将套接字绑定到本地地址及端口*/
client.bind(localAddress);
client.isBound();//判断套接字是否绑定
/*尝试连接到远处的服务器*/
client.connect(removeAddress);
/*创建套接字输入输出流,该步骤在链接成功之后,与服务器创建*/
in = client.getInputStream();//将in设为此套接字的输入流
din = new DataInputStream(in);//基于in创建数据输入流
out = client.getOutputStream();//将out设为此套接字的输出流
dout = new DataOutputStream(out);//基于out创建数据输出流
/*循环交互*/
while(true) {
/*利用输出流传输数据*/
dout.writeUTF(scan.next());//writeUTF写入字符串
/*从输入流接受数据*/
System.out.println(din.readUTF());//readUTF读取字符串
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
/*在不需要套接字实例时,通常必须关闭套接字(首先关闭基于套接字建立的输入和输出流)
*通过socket.shutdownOutput/Input()关闭输入输出流,连接会保持
*通过in/out.close()会直接关闭socket
* */
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务器
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
/***
* @date 2020/8/17
* @author Vbird
*
*/
public class Server {
public static void main(String[] args) {
ServerSocket server = null;//创建服务器套接字
Socket client =null;//用于接收某一客户端套接字发送的连接
InputStream in = null;//声明一个输入流
OutputStream out = null;//声明一个输出流
DataInputStream din = null;//创建用于传输数据的输入流
DataOutputStream dout = null;//创建用于传输数据的输出流
try {
/*创建非绑定服务器套接字*/
server = new ServerSocket();
/*将server服务器套接字绑定到本地地址9898端口*/
server.bind(new InetSocketAddress("localhost",9898));
/*测试服务器套接字是否绑定*/
server.isBound();
while(true){//循环等待客户端连接
System.out.println("等待连接......");
/*服务器接收连接请求
*在接收到请求之前,处于线程阻塞状态,后方代码将不会运行,与控制台输入时未接收到输入数据相同
* */
client = server.accept();//将服务器套接字接收到的连接存入client
System.out.println("连接成功");
/*创建套接字输入输出流,该步骤在连接之后,为某一客户端套接字创建唯一的输入输出流*/
in = client.getInputStream();//将in设为接受到的套接字的输入流
din = new DataInputStream(in);//基于in创建数据输入流
out = client.getOutputStream();//将out设为接收到的套接字的输出流
dout = new DataOutputStream(out);//基于out创建数据输出流
/*循环交互*/
while(true) {
/*从输入流接受数据*/
System.out.println(din.readUTF());
/*通过输出流输出数据*/
dout.writeUTF("已接收");
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
/*关闭服务器套接字*/
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
DatagramPacket
DatagramPacket概述
- DatagramPacket类表示用户数据报包,数据报包用来实现无连接数据包投递服务。数据报包中可以包含各种类型的数据对象。
- 每条报文只根据该包中包含的信息(通常是url和端口号)从一台机器路由到另一台机器
- 从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同顺序到达。不对包投递做出保证
DatagramPacket常用构造器
- public DatagramPacket(byte[] buf,int len):构建用来接收长度为len的数据包,len必须小于等于buf长度,byte数组为缓冲区,len为缓冲区长度
- pulbic DatagramPacket(byte[] bug,ing len,SocketAddress add):用来接收长度为len的数据包,并指定发送目的地址,byte数组为缓冲区,len为缓冲区长度
- public DatagramPacket(byte[] buf,int len,InetAddress add,int port):构建用来接收长度为len的数据包,并指定发送目的地址和端口号,byte数组为缓冲区,len为缓冲区长度
/*发送数据包*/
byte[] bys = new String("正在测试").getBytes();//需要发送的数据缓冲区
DatagramPacket dp = new DatagramPacket(bys,bys.length);
/*接收数据包*/
byte[] bys2 =new byte[60];//接收数据包缓冲区
DatagramPacket dp2 = new DatagramPacket(bys2,bys2.length);
DatagramPacket常用实例方法
- public void setData(byte[] buf):设置数据缓冲区
- public void setSocketAddress(SocketAddress address,int port):设置数据包发送的地址和端口号
- public void setLength(int length):设置数据包缓冲区长度
- public byte[] getData():以字节数组形式获取数据包缓冲区中的数据
- public int getLength():返回将要发送或接收的数据长度
DatagramSocket
DatagramSocket概述
DatagramSocket类表示用来发送和接收数据报包的套接字。
数据报套接字是包投递服务的发送或接收的端点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
DatagramSocket构造器
- public DatagramSocket()throws SocketException:构造数据报套接字并将其绑定到本地主机上任何可用的端口,随机绑定端口,接收数据时未知端口导致无法接收,意义不大
- public DatagramSocket(int port)throws SocketException:创建数据报套接字并将其绑定到本地主机上的指定端口
- public DatagramSocket(int port,InetAddress add)throws SocketException:创建数据报套接字,将其绑定到指定的本地地址
- public DatagramSocket(SocketAddress add)throws SocketException:创建数据报套接字,将其绑定到指定的本地套接字
DatagramSocket常用实例方法
- public void bind(SocketAddress addr)throws SocketException:将数据宝套接字绑定到某一地址
- public void connect(SocketAddress add)throws SocketException:连接远处的套接字地址
- public void disconnect():断开套接字连接,但没有释放套接字所占的资源,可以重新连接
- public void receive(DatagramPacket p):接收数据包
- public void send (DatagramPacket p):发送数据包
- public void close():关闭数据报套接字
数据报套接字信息交互
客户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
/***
* @date 2020/8/17
* @author Vbird
*
*/
public class ClientTest {
public static void main(String[] args) {
/*发送数据包*/
byte[] bys = new String("正在测试").getBytes();//需要发送的数据缓冲区
DatagramPacket dp = new DatagramPacket(bys,bys.length);
/*接收数据包*/
byte[] bys2 =new byte[60];//接收数据包缓冲区
DatagramPacket dp2 = new DatagramPacket(bys2,bys2.length);
/*创建远程地址对象*/
SocketAddress addr = new InetSocketAddress("localhost",9696);
/*创建本地数据报套接字对象*/
DatagramSocket ds = null;
try {
ds = new DatagramSocket(8886);//创建发送和接收数据的数据报套接字并绑定到8888接口
ds.connect(addr);//连接到远程服务器
System.out.println("连接状态为"+ds.isConnected());//判断是否连接
/*发送数据报包*/
ds.send(dp);
/*接收数据报包*/
ds.receive(dp2);
bys2 = dp2.getData();
System.out.println(new String(bys2));
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
/***
* @date 2020/8/17
* @author Vbird
*
*/
public class DatagramSocketTest {
public static void main(String[] args) {
/*接收数据包*/
byte[] bys = new byte[50];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
/*创建本地地址对象*/
SocketAddress addr = new InetSocketAddress("localhost",9696);
/*创建数据报套接字*/
DatagramSocket ds = null;
try {
ds = new DatagramSocket(addr);//将数据报套接字绑定到本地地址
/*接收数据*/
ds.receive(dp);
bys = dp.getData();
System.out.println(new String(bys));
/*发送数据包*/
byte[] bys2 = new String("已接收"+new String(bys)).getBytes();
DatagramPacket dp2= new DatagramPacket(bys2,bys2.length);
dp2.setAddress(InetAddress.getByName("localhost"));//绑定本机地址
dp2.setPort(8886);//设置为客户端端口号
/*发送数据*/
ds.send(dp2);
} catch (IOException e) {
e.printStackTrace();
}
}
}
数据报套接字基于UDP协议,Socket套接字基于TCP协议