网络编程
网络编程:借助网络,自己编写应用程序,数据交互或者信息交流
网站编程: 是借助浏览器来实现与现有的服务器之间交互
一.网络通信协议
- 我们在使用程序进行网络数据传输的时候需要遵循的网络协议(TCP/IP)。
1.OSI模型和TCP模型的对比
2.三次握手四次挥手
TCP协议的数据交互流程
- 发送请求,我想连接你
- 允许客户端连接
- 发送数据给服务端
关闭连接的操作
- TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
- 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
- 服务器关闭客户端的连接,发送一个FIN给客户端。
- 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。
二.IP地址的表示
- InetAddress
1.常用方法
- byte[]
getAddress() 返回此 InetAddress 对象的原始 IP 地址。 - static InetAddress[]
getAllByName(String host) 在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。 - static InetAddress
getByAddress(byte[] addr) 在给定原始 IP 地址的情况下,返回 InetAddress 对象。 - static InetAddress
getByAddress(String host, byte[] addr) 根据提供的主机名和 IP 地址创建 InetAddress。 - static InetAddress
getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。 - String
getHostAddress() 返回 IP 地址字符串(以文本表现形式)。 - String
getHostName() 获取此 IP 地址的主机名。 - static InetAddress
getLocalHost() 返回本地主机。
public class IpDemo {
public static void main(String[] args) throws UnknownHostException {
//获取IP地址,本机IP地址,网络地址
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);//DESKTOP-4GUP2FO/192.168.137.1
System.out.println("ip地址"+localHost.getHostAddress());//ip地址192.168.137.1
System.out.println("主机名字"+localHost.getHostName());//主机名字DESKTOP-4GUP2FO
System.out.println("========================");
//外网的话一定要联网,数可以是ip地址,也可以是域名
InetAddress taobao = InetAddress.getByName("www.taobao.com");
System.out.println(taobao);//www.taobao.com/118.123.2.248
System.out.println("ip地址"+taobao.getHostAddress());//ip地址118.123.2.248
System.out.println("主机名字"+taobao.getHostName());//主机名字www.taobao.com
}
}
- dos获取指定域名的ip信息
三.UDP协议
- UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接.
具体使用 : - DatagramPacket表示存放数据的数据报,DatagramSocket表示接受或发送数据报的套接字
1.构造方法
只放数据
- DatagramPacket(byte[] buf, int length) 构造 DatagramPacket,用来接收长度为 length 的数据包。
目标对象和数据
- DatagramPacket(byte[] buf, int length, InetAddress address, int port) 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
- DatagramPacket(byte[] buf, int offset, int length) 构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量。
- DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。
- DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) 构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。
- DatagramPacket(byte[] buf, int length, SocketAddress address) 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
2.常用方法
- InetAddress
getAddress() 返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。 - byte[]
getData() 返回数据缓冲区。 - int
getLength() 返回将要发送或接收到的数据的长度。 - int
getOffset() 返回将要发送或接收到的数据的偏移量。 - int
getPort() 返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。 - SocketAddress
getSocketAddress() 获取要将此包发送到的或发出此数据报的远程主机的 SocketAddress(通常为 IP 地址 + 端口号)。 - void
setAddress(InetAddress iaddr) 设置要将此数据报发往的那台机器的 IP 地址。 - void
setData(byte[] buf) 为此包设置数据缓冲区。 - void
setData(byte[] buf, int offset, int length) 为此包设置数据缓冲区。 - void
setLength(int length) 为此包设置长度。 - void
setPort(int iport) 设置要将此数据报发往的远程主机上的端口号。 - void
setSocketAddress(SocketAddress address) 设置要将此数据报发往的远程主机的 SocketAddress(通常为 IP 地址 + 端口号)。
3.DatagramSocket
3.1DatagramSocket构造方法
- DatagramSocket() 构造数据报套接字并将其绑定到本地主机上任何可用的端口。
- protected DatagramSocket(DatagramSocketImpl impl) 创建带有指定 DatagramSocketImpl 的未绑定数据报套接字。
- DatagramSocket(int port) 创建数据报套接字并将其绑定到本地主机上的指定端口。
- DatagramSocket(int port, InetAddress laddr) 创建数据报套接字,将其绑定到指定的本地地址。
- DatagramSocket(SocketAddress bindaddr) 创建数据报套接字,将其绑定到指定的本地套接字地址。
3.2DatagramSocket常用方法
- 都需要从DatagramPacket获取数据或者发送.
- void
receive(DatagramPacket p) 从此套接字接收数据报包。 - void
send(DatagramPacket p) 从此套接字发送数据报包。
发送端
- 创建datagramsocket
- 创建datagrampacket
- datagramsocket 发送 datagrampacket
Client.java
public class Client {
public static void main(String[] args) throws IOException {
//创建DatagramSocket
DatagramSocket datagramSocket=new DatagramSocket();
//键盘输入
System.out.println("请输入要发送的数据:");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String mess = br.readLine();
byte [] bytes=mess.getBytes();
//创建datagrampacket,将发送的内容保存就进去
DatagramPacket datagramPacket=new DatagramPacket(bytes,bytes.length);
datagramPacket.setAddress(InetAddress.getByName("127.0.0.1"));
datagramPacket.setPort(8989);
//datagramsocket发送datagrampacket
datagramSocket.send(datagramPacket);
System.out.println("数据发送成功");
}
}
接收端
- 创建datagramsocket
- 创建datagrampacket
- datagramsocket 接收数据 保存到datagrampacket
- 将信息打印出来datagrampacket
Server.java
public class Server {
public static void main(String[] args) throws IOException {
System.out.println("接收端已经启动等待接收数据");
//创建datagramsocket,该接收端的ip地址是本地ip
DatagramSocket datagramSocket=new DatagramSocket(8989);
//创建datagrampacket
byte[] bytes=new byte[100];
DatagramPacket datagramPack=new DatagramPacket(bytes,100);
//datagramsocket接收数据,保存到datagrampacket
datagramSocket.receive(datagramPack);//程序会进入到阻塞状态
//将信息打印出来datagrampacket
System.out.println("接收到的信息是"+new String(bytes));
System.out.println("发送者的IP地址:"+datagramPack.getAddress());
System.out.println("发送者的port地址是"+datagramPack.getPort());
//获取发送来的数据
byte[] data=datagramPack.getData();
}
}
四.TCP协议
-
TCP在使用的时候,必须先启动服务端,才可以使用客户端.
-
TCP协议是面向连接的通信协议,即在传输数据前先在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输(打电话).
1.服务端ServerSocket的构造方法(设置端口号)
- ServerSocket() 创建非绑定服务器套接字。
- ServerSocket(int port) 创建绑定到特定端口的服务器套接字。
- ServerSocket(int port, int backlog) 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
- ServerSocket(int port, int backlog, InetAddress bindAddr) 使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。
2.Socket
2.1Socket的构造方法
- Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字
- Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
2.2常用方法
Socket
accept() 侦听并接受到此套接字的连接。
客户端
- 创建socket,指定目标主机,端口号.
- 创建输出流.
- 将数据通过输出流,发送给服务端.
- 刷新资源.
Client .java
public class Client {
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入你要发送的内容");
//发送的内容
String message = br.readLine();
//创建客户端socket
Socket socket=new Socket(InetAddress.getByName("192.168.1.241"),12306);
//创建输出流
OutputStream out = socket.getOutputStream();
out.write(message.getBytes());
out.flush();
out.close();
System.out.println("发送成功");
}
}
服务端
- 创建serversocket,设置端口号,设置ip地址,不设置为本机.
- 获取socket,accept()服务端阻塞.
- 通过socket,获取input流.
- 从input流中,获取客户端发送来得数据 .
Server .java
public class Server {
public static void main(String[] args) throws IOException {
//创建ServerSocket服务器,设置端口号,设置ip地址
ServerSocket server=new ServerSocket(12306);
System.out.println("服务器已经启动");
while(true) {
//监听客户端的操作,得到socket对象
Socket socket=server.accept();
//得到客户端信息
InetAddress inetAddress = socket.getInetAddress();
System.out.println("ip地址"+inetAddress.getHostAddress()+"端口号"+socket.getLocalPort());
//创建输入流
InputStream inputStream = socket.getInputStream();
byte [] bytes=new byte[inputStream.available()];
inputStream.read(bytes);
System.out.println("发来的信息是:"+new String(bytes));
inputStream.close();
}
}
}