- Java为TCP协议提供了两个类:Socket和ServerSocket。
- 一个Socket实例代表TCP连接的一端。
- 一个TCP连接是一条抽象的双向通道,两端由IP地址和端口号确定。
- 建立TCP连接的过程:
(1) 客户端TCP向服务端TCP发送连接请求。
(2) ServerSocket实例监听TCP连接请求,并为请求创建新的Socket实例。也就是说,服务器端要同时处理ServerSocket实例和Socket实例,而客户端只需要使用Socket实例。
2.2.1 TCP客户端
TCP连接请求的三个步骤:
1. 创建一个Socket实例,指定远程主机和端口,建立一个TCP连接;
2. 通过套接字的I/O流进行通信:一个Socket实例包括一个InputStream和一个OutputStream。用法与Java的I/O流相同;
3. 使用Socket类的close()关闭连接。
示例程序:
public class TcpClient {
public static void main(String[] args) throws IOException{
Socket client = new Socket(TcpServer.LOCAL_HOST, TcpServer.PORT);
PrintWriter sender = new PrintWriter(client.getOutputStream(), true);
sender.println("From client:Hello, TcpServer...");
BufferedReader receiver = new BufferedReader(new InputStreamReader(client.getInputStream()));
String receiveLine = null;
if((receiveLine = receiver.readLine())!=null){
System.out.println(receiveLine);
}
client.close();//结束后请记得close client
}
}
Socket:创建
// 前两个没有指定本地地址和端口号,将采用默认地址和可用端口号
Socket(InetAddress remoteAddr, int remotePort);
Socket(String remoteHost, int remotePort);
//在有多个接口的主机上指定本地地址时有用的
Socket(InetAddress remoteAddr, int remotePort, InetAddress localAddr, int localPort);
Socket(String remoteHost, int remotePort, InetAddress localAddr, int localPort);
//创建一个没有连接的套接字,使用它之前必须显式连接。
Socket()
前四个构造函数在创建了一个TCP套接字后,先连接到指定的远程地址和端口号,再将其返回给程序。
Socket:操作
// 在使用Socket()构造方法构建的Socket实例时需要使用此方法显式连接
void connect(SocketAddress destination);
void connect(SocketAddress destination, int timeout);
InputStream getInputStream();
OutputStream getOutputStream();
// 关闭套接字及其关联的I/O流,从而阻止对其进一步操作。
void close();
// 关闭TCP的输入流,任何没有读取的数据(包括套接字缓存的数据、正在传输的数据和将要到达的数据)都将被舍弃。后续的任何从套接字读取数据的操作都将抛出异常。
void shutdownInput();
// 与前者类似,但已经写入套接字输出流的数据,将被尽量保证能发送到另一端。
void shutdownOutput();
Socket:获取/检测属性
InetAddress getInetAddress();
int getPort();
InetAddress getLocalAddress();
int getLocalPort();
// 其实返回值都是InetSocketAddress实例,其中封装了一个InetAddress和一个端口号。
SocketAddress getRemoteSocketAddress();
SocketAddress getLocalSocketAddress();
InetSocketAddress:创建与访问
InetSocketAddress(InetAddress addr, int port);
// 使用“任何”地址创建实例
InetSocketAddress(int port);
// 将主机名解析成IP地址
InetSocketAddress(String hostname, int port);
// 不解析主机名的情况下创建实例
static InetSocketAddress createUnresolved(String host, int port);
//创建InetAddressSocket实例时未对主机名解析或解析失败则返回true
boolean isUnresolved();
InetAddress getAddress();
int getPort();
String getHostName();
String toString();
2.2.2 TCP服务器端
建立TCP服务器的步骤:
1. 创建一个ServerSocket实例并指定本地端口。此套接字的功能是侦听该指定端口收到的连接。
2. 重复执行:
(1). 调用ServerSocket的accept()方法获取下一个客户端连接。基于新建立的客户端连接,创建一个Socket实例,并由accept()返回。
(2). 使用Socket实例的I/O流与客户端通信。
(3). 通信完成,调用Socket实例的close()关闭套接字连接。
示例程序:
public class TcpServer {
public static final String LOCAL_HOST = "127.0.0.1";
public static final int PORT = 8080;
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(PORT);
Socket client = null;
while(true){
client = server.accept();
BufferedReader receiver = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter sender = new PrintWriter(client.getOutputStream(), true);
String receiveLine = null;
if((receiveLine = receiver.readLine())!=null){
System.out.println(receiveLine);
sender.println("From server:欢迎访问TcpServer");
}
client.close();
}
}
}