Java 教程
- Java - 首页
- Java - 概述
- Java - 历史
- Java - 特性
- Java 与 C++
- JVM - Java 虚拟机
- Java - JDK 与 JRE 与 JVM
- Java - Hello World 程序
- Java - 环境搭建
- Java - 基本语法
- Java - 变量类型
- Java - 数据类型
- Java - 类型转换
- Java - Unicode 系统
- Java - 基本运算符
- Java - 注释
- Java - 用户输入
- Java - 日期与时间
Java 控制语句
- Java - 循环控制
- Java - 决策制定
- Java - if-else
- Java - switch
- Java - for 循环
- Java - for-each 循环
- Java - while 循环
- Java - do-while 循环
- Java - break
- Java - continue
面向对象编程
- Java - OOPs 概念
- Java - 对象与类
- Java - 类属性
- Java - 类方法
- Java - 方法
- Java - 变量作用域
- Java - 构造函数
- Java - 访问修饰符
- Java - 继承
- Java - 聚合
- Java - 多态性
- Java - 方法重写
- Java - 方法重载
- Java - 动态绑定
- Java - 静态绑定
- Java - 实例初始化块
- Java - 抽象
- Java - 封装
- Java - 接口
- Java - 包
- Java - 内部类
- Java - 静态类
- Java - 匿名类
- Java - 单例类
- Java - 包装类
- Java - 枚举
- Java - 枚举构造函数
- Java - 枚举字符串
Java 内置类
Java 文件处理
Java 错误与异常
- Java - 异常
- Java - try-catch 块
- Java - try-with-resources
- Java - 多重 catch 块
- Java - 嵌套 try 块
- Java - finally 块
- Java - throw 异常
- Java - 异常传播
- Java - 内置异常
- Java - 自定义异常
Java 多线程
- Java - 多线程
- Java - 线程生命周期
- Java - 创建线程
- Java - 启动线程
- Java - 线程连接
- Java - 线程命名
- Java - 线程调度器
- Java - 线程池
- Java - 主线程
- Java - 线程优先级
- Java - 守护线程
- Java - 线程组
- Java - 关闭钩子
Java 同步
Java 网络编程
- Java - 网络编程
- Java - Socket 编程
- Java - URL 处理
- Java - URL 类
- Java - URLConnection 类
- Java - HttpURLConnection 类
- Java - Socket 类
- Java - 泛型
Java 集合
Java 接口
Java 数据结构
Java 集合算法
高级 Java
- Java - 命令行参数
- Java - Lambda 表达式
- Java - 发送邮件
- Java - Applet 基础
- Java - Javadoc 注释
- Java - 自动装箱和拆箱
- Java - 文件不匹配方法
- Java - REPL (JShell)
- Java - 多发行版 Jar 文件
- Java - 私有接口方法
- Java - 内部类菱形运算符
- Java - 多分辨率图像 API
- Java - 集合工厂方法
- Java - 模块系统
- Java - Nashorn JavaScript
- Java - Optional 类
- Java - 方法引用
- Java - 函数式接口
- Java - 默认方法
- Java - Base64 编码解码
- Java - switch 表达式
- Java - Teeing 收集器
- Java - 微基准测试
- Java - 文本块
- Java - 动态 CDS 归档
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指针异常
- Java - 打包工具
- Java - 密封类
- Java - 记录类
- Java - 隐藏类
- Java - 模式匹配
- Java - 简洁数字格式化
- Java - 垃圾回收
- Java - JIT 编译器
Java 杂项
- Java - 递归
- Java - 正则表达式
- Java - 序列化
- Java - 字符串
- Java - Process API 改进
- Java - Stream API 改进
- Java - 增强的 @Deprecated 注解
- Java - CompletableFuture API 改进
- Java - 流
- Java - 日期时间 API
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java API 与框架
Java 类参考
- Java - Scanner
- Java - 数组
- Java - 字符串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java 有用资源
Java - Socket 类及示例
Sockets 使用 TCP 提供两台计算机之间的通信机制。客户端程序在其通信端创建一个套接字,并尝试将该套接字连接到服务器。
连接建立后,服务器在其通信端创建一个套接字对象。客户端和服务器现在可以通过写入和读取套接字进行通信。
java.net.Socket 类表示套接字,java.net.ServerSocket 类为服务器程序提供了一种机制,用于监听客户端并与它们建立连接。
连接建立后,可以使用 I/O 流进行通信。每个套接字都有 OutputStream 和 InputStream。客户端的 OutputStream 连接到服务器的 InputStream,客户端的 InputStream 连接到服务器的 OutputStream。
Java Socket 类表示客户端和服务器用来相互通信的套接字。客户端通过实例化一个 Socket 对象来获取它,而服务器从 accept() 方法的返回值获取 Socket 对象。
声明
public class Socket
extends Object
implements Closeable
构造函数
| 序号 | 方法与描述 |
|---|---|
| 1 | public Socket() 此方法创建一个未连接的套接字,使用系统默认类型的 SocketImpl。 |
| 2 | public Socket(String host, int port) throws UnknownHostException, IOException 此方法尝试连接到指定端口上的指定服务器。如果此构造函数没有抛出异常,则连接成功,客户端已连接到服务器。 |
| 3 | public Socket(String host,int port,InetAddress localAddr,int localPort) throws IOException 此方法创建一个套接字并将其连接到指定的远程主机上的指定远程端口。套接字还将绑定()到提供的本地地址和端口。 |
| 4 | public Socket(InetAddress host, int port) throws IOException 此方法与上一个构造函数相同,只是主机由 InetAddress 对象表示。 |
| 5 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. 此方法与上一个构造函数相同,只是主机由 InetAddress 对象而不是 String 表示。 |
| 6 | public Socket(Proxy proxy) 此方法创建一个未连接的套接字,指定应使用的代理类型(如果有),而不管任何其他设置如何。 |
当 Socket 构造函数返回时,它不仅实例化一个 Socket 对象,而且实际上还尝试连接到指定的服务器和端口。
方法
这里列出 Socket 类中一些感兴趣的方法。请注意,客户端和服务器都有一个 Socket 对象,因此这些方法可以由客户端和服务器调用。
| 序号 | 方法与描述 |
|---|---|
| 1 | void bind(SocketAddress bindpoint) 将套接字绑定到本地地址。 |
| 2 |
关闭此套接字。 |
| 3 | void connect(SocketAddress endpoint) 将此套接字连接到服务器。 |
| 4 | void connect(SocketAddress endpoint, int timeout) 使用指定的超时值将此套接字连接到服务器。 |
| 5 |
返回与此套接字关联的唯一 SocketChannel 对象(如果有)。 |
| 6 |
返回套接字连接到的地址。 |
| 7 |
返回此套接字的输入流。 |
| 8 |
测试是否启用了 SO_KEEPALIVE。 |
| 9 |
获取套接字绑定的本地地址。 |
| 10 |
返回此套接字绑定的本地端口号。 |
| 11 | SocketAddress getLocalSocketAddress() 返回此套接字绑定的端点的地址。 |
| 12 |
测试是否启用了 SO_OOBINLINE。 |
| 13 | <T> T getOption(SocketOption<T> name) 返回套接字选项的值。 |
| 14 | OutputStream getOutputStream() 返回此套接字的输出流。 |
| 15 |
返回此套接字连接到的远程端口号。 |
| 16 |
获取此 Socket 的 SO_RCVBUF 选项的值,即平台在此 Socket 上输入使用的缓冲区大小。 |
| 17 | SocketAddress getRemoteSocketAddress() 返回此套接字连接到的端点的地址,如果未连接则返回 null。 |
| 18 |
测试是否启用了 SO_REUSEADDR。 |
| 19 |
获取此 Socket 的 SO_SNDBUF 选项的值,即平台在此 Socket 上输出使用的缓冲区大小。 |
| 20 |
返回 SO_LINGER 的设置。 |
| 21 |
返回 SO_TIMEOUT 设置。返回值为 0 表示该选项被禁用(即超时时间为无限大)。 |
| 22 |
测试 TCP_NODELAY 是否启用。 |
| 23 |
获取从该 Socket 发送的数据包的 IP 头部中的流量类或服务类型。 |
| 24 |
返回套接字的绑定状态。 |
| 25 |
返回套接字的关闭状态。 |
| 26 |
返回套接字的连接状态。 |
| 27 |
返回套接字连接的读取部分是否已关闭。 |
| 28 |
返回套接字连接的写入部分是否已关闭。 |
| 29 | void sendUrgentData(int data) 在套接字上发送一个字节的紧急数据。 |
| 30 |
启用/禁用 SO_KEEPALIVE。 |
| 31 |
启用/禁用 SO_OOBINLINE(TCP 紧急数据的接收)。默认情况下,此选项被禁用,在套接字上接收到的 TCP 紧急数据将被静默丢弃。 |
| 32 | <T> Socket setOption(SocketOption<T> name, T value) 设置套接字选项的值。 |
| 33 | void setPerformancePreferences(int connectionTime, int latency, int bandwidth) 设置此套接字的性能偏好。 |
| 34 | void setReceiveBufferSize(int size) 将此 Socket 的 SO_RCVBUF 选项设置为指定的值。 |
| 35 | void setReuseAddress(boolean on) 启用/禁用 SO_REUSEADDR 套接字选项。 |
| 36 | void setSendBufferSize(int size) 将此 Socket 的 SO_SNDBUF 选项设置为指定的值。 |
| 37 | static void setSocketImplFactory(SocketImplFactory fac) 为应用程序设置客户端套接字实现工厂。 |
| 38 | void setSoLinger(boolean on, int linger) 启用/禁用 SO_LINGER,并指定以秒为单位的延迟时间。 |
| 39 | void setSoTimeout(int timeout) 启用/禁用 SO_TIMEOUT,并指定以毫秒为单位的超时时间。 |
| 40 | void setTcpNoDelay(boolean on) 启用/禁用 TCP_NODELAY(禁用/启用 Nagle 算法)。 |
| 41 |
设置从该 Socket 发送的数据包的 IP 头部中的流量类或服务类型八位字节。 |
| 42 |
将此套接字的输入流置于“流结束”状态。 |
| 43 |
禁用此套接字的输出流。 |
| 44 | Set<SocketOption<?>> supportedOptions() 返回此套接字支持的套接字选项集。 |
| 45 |
将此套接字转换为字符串。 |
客户端示例
下面的 GreetingClient 是一个客户端程序,它使用套接字连接到服务器,发送问候语,然后等待响应。
示例
package com.tutorialspoint;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class GreetingClient {
public static void main(String [] args) {
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try {
System.out.println("Connecting to " + serverName + " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
下面的 GreetingServer 程序是一个服务器应用程序示例,它使用 Socket 类监听指定端口号上的客户端(端口号由命令行参数指定)。
package com.tutorialspoint;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class GreetingServer extends Thread {
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run() {
while(true) {
try {
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
+ "\nGoodbye!");
server.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String [] args) {
int port = Integer.parseInt(args[0]);
try {
Thread t = new GreetingServer(port);
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
编译客户端和服务器,然后按如下方式启动服务器:
$ java GreetingServer 6066 Waiting for client on port 6066... Just connected to /127.0.0.1:49462 Hello from /127.0.0.1:49462 Waiting for client on port 6066...
按如下方式检查客户端程序:
输出
$ java GreetingClient localhost 6066 Connecting to localhost on port 6066 Just connected to localhost/127.0.0.1:6066 Server says Thank you for connecting to /127.0.0.1:6066 Goodbye!