Socket = IP 地址 + 端口号
Socket 是网络上运行的程序之间双向通信链路的终结点,是 TCP 和 UDP 的基础。
- ftp:
21
- telent:
23
- http:
80
- ...
针对网络通信的不同层次, Java 提供的网络功能的四大类:
InetAddress
:用于标识网络上的硬件资源URL
:统一资源定位符,通过 URL 可以直接读取或写入网络上的资源Socket
:使用 TCP 协议实现网络通信的 Socket 相关的类Datagram
:使用 UDP 协议,数据保存数据报中,通过网络进行通信
InetAddressaddress =InetAddress.getLocalHost();System.out.println(address.getHostName());System.out.println(address.getHostAddress());System.out.println(Arrays.toString(address.getAddress()));System.out.println(address);
try {URLurl =newURL("https://www.baidu.com");InputStreamis =url.openStream();InputStreamReaderisr =newInputStreamReader(is,StandardCharsets.UTF_8);BufferedReaderbr =newBufferedReader(isr);Stringdata =br.readLine();while (data !=null) {System.out.println(data);data =br.readLine(); }br.close();isr.close();is.close();}catch (IOExceptione) {e.printStackTrace();}
TCP 协议(传输控制协议)是面向连接、可靠的、有序的、以字节流发送数据。
Java 中基于 TCP 协议实现网络通信的类
- 客户端的
Socket
类 - 服务端的
ServerSocket
类

Socket 通信实现步骤
- 创建
ServerSocket
和Socket
- 打开连接到
Socket
的输入/输出流 - 按照协议对
Socket
进行读写操作 - 关闭输入/输出流,关闭
Socket
- 创建
ServerSocket
对象,绑定监听端口 - 通过
accept()
方法监听客户端请求 - 连接建立后,通过输入流读取客户端发送的请求信息
- 通过输出流向客户端发送响应信息
- 关闭相应资源
// 1. 创建 ServerSocket 对象,绑定监听端口ServerSocketserverSocket =newServerSocket(8888);System.out.println("***服务器已经启动,开始侦听客户端的连接***");// 2. 通过 accept() 方法监听客户端请求Socketsocket =serverSocket.accept();// 3. 连接建立后,通过输入流读取客户端发送的请求信息InputStreamis =socket.getInputStream();InputStreamReaderisr =newInputStreamReader(is);BufferedReaderbr =newBufferedReader(isr);Stringinfo =null;while ((info =br.readLine()) !=null) {System.out.println("我是服务器,客户端说:" +info);}socket.shutdownInput();// 关闭输入流// 4. 通过输出流向客户端发送响应信息OutputStreamos =socket.getOutputStream();PrintWriterpw =newPrintWriter(os);pw.write("欢迎你");pw.flush();// 5. 关闭相应资源pw.close();os.close();br.close();isr.close();is.close();socket.close();serverSocket.close();
- 创建
Socket
对象,指明需要连接的服务的地址和端口号 - 连接建立后,通过输出流向服务发送请求信息
- 通过输入流获取服务响应的信息
- 关闭相应资源
// 1. 创建 Socket 对象,指明需要连接的服务器的地址和端口号Socketsocket =newSocket("127.0.0.1",8888);// 2. 连接建立后,通过输出流向服务器发送请求信息OutputStreamos =socket.getOutputStream();PrintWriterpw =newPrintWriter(os);pw.write("user:zhangsan;passwd:123456");pw.flush();socket.shutdownOutput();// 关闭输出流// 3. 通过输入流获取服务器响应的信息InputStreamis =socket.getInputStream();InputStreamReaderisr =newInputStreamReader(is);BufferedReaderbr =newBufferedReader(isr);Stringresp =null;while ((resp =br.readLine()) !=null) {System.out.println("我是客户端,服务器说:" +resp);}socket.shutdownInput();// 关闭输入流// 4. 关闭相应资源pw.close();os.close();br.close();isr.close();is.close();socket.close();
- 服务端创建
ServerSocket
,循环调用accept()
等待客户端连接 - 客户端创建一个
Socket
并请求和服务端连接 - 服务端接受客户端请求,创建
Socket
与该客户端建立专线连接 - 建立连接的两个
Socket
在一个单独的 x 线程上对话 - 服务端继续等待新的连接
// 1. 创建 ServerSocket 对象,绑定监听端口ServerSocketserverSocket =newServerSocket(8888);System.out.println("***服务器已经启动,开始侦听客户端的连接***");intcount =0;// 2. 通过 accept() 方法监听客户端请求Socketsocket;while (true) {socket =serverSocket.accept();ServerThreadthread =newServerThread(socket);thread.setPriority(4);thread.start();count++;System.out.println("客户端的数量为:" +count);InetAddressaddress =socket.getInetAddress();System.out.println("当前客户端的地址为:" +address.getHostAddress());}
UDP 协议(用户数据报协议)是无连接、不可靠的、无序的。
UDP 协议传输速度快。
UDP 协议以数据报作为数据传输的载体。
使用 UDP 协议进行数据传输时,
- 创建
DatagramSocket
,指定端口号 - 创建
DatagramPacket
- 接受客户端发送的数据信息
- 读取数据
// 1. 创建 DatagramSocket,指定端口号DatagramSocketsocket =newDatagramSocket(8888);// 2. 创建 DatagramPacketbyte[]data =newbyte[1024];DatagramPacketpacket =newDatagramPacket(data,data.length);System.out.println("***服务器已经启动,开始侦听客户端的连接***");// 3. 接受客户端发送的数据信息// 此方法在接收到数据之前按一直会保持阻塞socket.receive(packet);// 4. 读取数据Stringinfo =newString(data,0,packet.getLength());System.out.println("我是服务器,客户端说:" +info);// 服务器向客户端进行响应InetAddressaddress =packet.getAddress();intport =packet.getPort();byte[]resp ="你好,这是服务器对客户端的响应".getBytes();DatagramPacketrespPacket =newDatagramPacket(resp,resp.length,address,port);socket.send(respPacket);socket.close();
- 定义发送信息
- 创建
DatagramPacket
,包含所要发送的信息 - 创建
DatagramSocket
- 发送数据
// 1. 定义发送信息InetAddressaddress =InetAddress.getLocalHost();intport =8888;byte[]data ="user:zhangsan;passwd:888888".getBytes();// 2. 创建 DatagramPacket,包含所要发送的信息DatagramPacketpacket =newDatagramPacket(data,data.length,address,port);// 3. 创建 DatagramSocketDatagramSocketsocket =newDatagramSocket();// 4. 发送数据socket.send(packet);// 客户端接收服务器端的响应byte[]resp =newbyte[1024];DatagramPacketrespPacket =newDatagramPacket(resp,resp.length);socket.receive(respPacket);Stringinfo =newString(resp,0,respPacket.getLength());System.out.println("我是客户端,服务器响应的信息为:" +info);
- 线程优先级
- 对于同一个
Socket
- 如果关闭了输出流,则与该输出流关联的
Socket
也会被关闭 - 所以一般不需要关闭流,直接关闭
Socket
即可
- TCP 传输字符串、对象
Socket
传递文件