TCP网络编程
1 概述
在TCP通信协议下,计算机网络中不同设备上的应用程序之间可以通信,通信时需严格区分客户端(Client)与服务器端(Server)。
在Java中,对于这样基于TCP协议下连接通信的客户端和服务端,分别进行了抽象:
java.net.ServerSocket
类表示服务端java.net.Socket
类表示客户端
使用Socket
和ServerSocket
进行的编程,也称为套接字编程。
2 通信流程
TCP客户端和服务器进行通信,其通信流程是固定的,具体如下:
服务器端:
-
创建ServerSocket(需绑定端口,方便客户端连接)
-
调用ServerSocket对象的accept()方法接收一个客户端请求,得到一个Socket
-
调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
输入流可以读取客户端发送过来的数据
输出流可以发送数据到客户端
-
操作完成,关闭资源
构造方法
方法名 | 说明 |
---|---|
ServletSocket(int port) | 创建绑定到指定端口的服务器套接字 |
相关方法
方法名 | 说明 |
---|---|
Socket accept() | 监听要连接到此的套接字并接受它 |
注意:accept方法是阻塞的,作用是等待客户端连接,如果有客户端连接则立马返回,如果没有客户端连接则一致阻塞等待。
客户端:
-
创建Socket连接服务端(需指定服务器ip地址、端口),找对应的服务器进行连接
-
调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
输入流可以读取服务端输出流写出的数据
输出流可以写出数据到服务端的输入流
-
操作完成,关闭资源
注意,在整个过程中,服务端不能主动连接客户端,必须由客户端先行发起连接才行
构造方法
方法名 | 说明 |
---|---|
Socket(InetAddress address,int port) | 创建流套接字并将其连接到指定IP指定端口号 |
Socket(String host, int port) | 创建流套接字并将其连接到指定主机上的指定端口号 |
相关方法
方法名 | 说明 |
---|---|
InputStream getInputStream() | 返回此套接字的输入流 |
OutputStream getOutputStream() | 返回此套接字的输出流 |
![image-20230404102402578](asserts/image-20230404102402578.png)
3 基础案例
搭建TCP客户端,发送信息到服务器
package com.briup.chap12;
public class Test063_TcpClient {
public static void main(String[] args) throws Exception {
//1.创建Socket对象(指定服务器ip port) 连接到服务器
Socket socket = new Socket("127.0.0.1",8989);
System.out.println("成功连接到 8989服务器,socket: " + socket);
//2.获取数据传输的IO流
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//3.数据传输【跟服务器 业务配合 起来】
// 先发送数据给服务器
os.write("hello server, 我是Tcp客户端".getBytes());
System.out.println("数据发送完成!");
// 再接收从服务器返回的数据
byte[] buff = new byte[1024];
int len = is.read(buff);
System.out.println("read: " + new String(buff,0,len));
//4.关闭资源
os.close();
is.close();
socket.close();
}
}
搭建TCP服务器端,接收客户端发送的信息,并返回数据给客户端
package com.briup.chap12;
public class Test063_TcpServer {
public static void main(String[] args) throws IOException {
// 1.创建ServerSocket(需绑定端口,方便客户端连接)
ServerSocket server = new ServerSocket(8989);
System.out.println("服务器成功启动,端口 8989 ...");
//2.调用ServerSocket的accept()方法接收客户端请求,得到一个Socket
// 如果客户端成功连接到服务器,直接返回 套接字对象(通信)
// 如果没有客户端连接 服务器,则阻塞
Socket socket = server.accept();
System.out.println("客户端成功连接: " + socket);
//3.获取网络通信的IO流对象
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//4.数据传输
// 先读取 客户端发送过来的数据 并输出
byte[] buff = new byte[1024];
int len = is.read(buff);
System.out.println("成功读取: ");
System.out.println(new String(buff,0,len));
// 再返回一条数据给 客户端
System.out.println("即将发送数据 给 客户端...");
os.write("hello world client".getBytes());
System.out.println("数据成功发送!");
//5.关闭资源
os.close();
is.close();
socket.close();
server.close();
}
}