1.套接字Socket
网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
1.1 构造函数
public Socket(InetAddress address,int port)创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
public Socket(String host,int port)创建一个流套接字并将其连接到指定主机上的指定端口号。
1.2 方法
public InputStream getInputStream()返回此套接字的输入流。可以用于接收网络消息
public OutputStream getOutputStream()返回此套接字的输出流。可以用于发送网络消息
public InetAddress getInetAddress()此套接字连接到的远程 IP 地址;如果套接字是未连接的,则返回 null。
public InetAddress getLocalAddress()获取套接字绑定的本地地址。 即本端的IP地址
public int getPort()此套接字连接到的远程端口号;如果尚未连接套接字,则返回 0。
public int getLocalPort()返回此套接字绑定到的本地端口。 如果尚未绑定套接字,则返回 -1。即本端的端口号。
public void close()关闭此套接字。套接字被关闭后,便不可在以后的网络连接中使用(即无法重新连接或重新绑定)。需要创建新的套接字对象。 关闭此套接字也将会关闭该套接字的 InputStream 和OutputStream。
public void shutdownInput()如果在套接字上调用 shutdownInput() 后从套接字输入流读取内容,则流将返回 EOF(文件结束符)。 即不能在从此套接字的输入流中接收任何数据。
public void shutdownOutput()禁用此套接字的输出流。对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。 如果在套接字上调用 shutdownOutput() 后写入套接字输出流,则该流将抛出 IOException。 即不能通过此套接字的输出流发送任何数据。
1.3 IP地址
InetAddress address = InetAddress.getByName(String s);// 一般s是域名,例如www.baidu.com
InetAddress address = InetAddress.getLocalHost(); // 获取本地地址
address.getHostName();// 获取域名
address.getHostAddress();// 获取IP
2.TCP客户端和服务器传输数据的步骤
2.1 客户端Socket工作的四个基本步骤
- 创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
- 打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输
- 按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
- 关闭 Socket:断开客户端到服务器的连接,释放线路
2.2 服务器工作的四个基本步骤
- 调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
- 调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
- 调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。
- 关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。
2.3 练习
从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接。
- 对于客户端和服务器之间的通信,必须使用Socket对象来获取输入或输出流。
- 客户端调用shutdownOutput()后,会在流的末尾写入一个结束标志,这样服务器才会读取到-1,跳出循环。
客户端:
@Test
public void test1() throws IOException {
// 1.创建客户端Socket对象,将服务端ip和端口号传入
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 8899);
// 2.获取输出流和输入流,开始网络数据的发送和接收
OutputStream outputStream = socket.getOutputStream();
// 3.传输文件
FileInputStream fis = new FileInputStream("img.png");
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
// 终止客户端输出,防止输出阻塞
socket.shutdownOutput();
// 接受服务器回传的消息
InputStream inputStream = socket.getInputStream();
byte[] buffer1 = new byte[1024];
while ((len = inputStream.read(buffer1)) != -1) {
System.out.println(new String(buffer1,0,len));
}
// 4.关闭资源
outputStream.close();
inputStream.close();
fis.close();
socket.close();
}
服务器:
public void test2() throws IOException {
// 1.创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
ServerSocket ss = new ServerSocket(8899);
// 2.监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象
Socket accept = ss.accept();
// 3.获取输出流和输入流,开始网络数据的发送和接收
InputStream inputStream = accept.getInputStream();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.png"));
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
// 向客户端回传数据
OutputStream outputStream = accept.getOutputStream();
outputStream.write("发送成功".getBytes());
// 4.关闭资源
inputStream.close();
bos.close();
outputStream.close();
accept.close();
ss.close();
}
3.UDP通信
3.1 概述
UDP是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。如同发快递包裹一样。
3.2 通信流程
- 创建DatagramSocket对象,用于客户端和服务器间的通信;
- 创建DatagramPacket对象,用于存储数据;
- 客户端socket对象调用send()发送数据;
- 服务器socket对象调用receive()接收数据;
- 关闭socket服务;
3.3 应用实例
客户端:
public void testClient() throws IOException {
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
DatagramSocket socket = new DatagramSocket();
String str = "hahahahah";
byte[] bytes = str.getBytes();
// 指定服务器地址和端口
DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length,inetAddress,9090);
// 发送数据
socket.send(dp);
socket.close();
}
服务器:
public void testSever() throws IOException {
// 指定服务器端口
DatagramSocket socket = new DatagramSocket(9090);
byte[] buffer = new byte[1024];
DatagramPacket dp = new DatagramPacket(buffer,0,buffer.length);
// 接收数据
socket.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
socket.close();
}
4.URL网络编程
4.1 URL的基本组成
https://www.bilibili.com/video/BV1Kb411W75N?p=629&spm_id_from=pageDriver
传输协议 域名 文件名 参数
4.2 方法
//public String getProtocol( ) 获取该URL的协议名
//public String getHost( ) 获取该URL的主机名
//public String getPort( ) 获取该URL的端口号
//public String getPath( ) 获取该URL的文件路径
//public String getFile( ) 获取该URL的文件名
//public String getQuery( ) 获取该URL的查询名(参数)
4.3 实例
public void testURL() throws MalformedURLException {
URL url = new URL("https://www.bilibili.com/video/BV1Kb411W75N?p=629&spm_id_from=pageDriver");
System.out.println(url.getProtocol());
System.out.println(url.getHost());
System.out.println(url.getPort());
System.out.println(url.getPath());
System.out.println(url.getFile());
System.out.println(url.getQuery());
//https
//www.bilibili.com
//-1
///video/BV1Kb411W75N
///video/BV1Kb411W75N?p=629&spm_id_from=pageDriver
//p=629&spm_id_from=pageDriver
}