目的:实现两台计算机之间的交互,通信两端要严格区分客户端和服务器端口
两端通信的步骤:
1. 服务端需要启动,等待客户端连接
2. 客户端需要主动地链接服务器端,链接成功才能通信,服务器端口不可以主动链接客户端在java中,提供两个类,实现TCP通信:
- 客户端:创建Socket对象,创建之后就相当于创建了客户端,向服务器端发送连接请求,服务器端回响一个请求表示已经接受,两者就建立了通信
- 服务器端:创建ServerSocket对象,创建之后就相当于,开启了一个服务,等待客户端连接
Socket类
socket类,实现客户端套接字,套接字指的是两台设备之间通讯的端点
构造方法
– public Socket(String host, int port) —-> 创建套接字对象并连接到主机的指定端口号,如果指定了host是一个null, 那么就相当于与指定地址为回送地址【127.x.x.x】,是本机的回送地址,主要用于网络软件测试使用,本机上进程间的通信。就不会进行网络传输
成员方法
– public InputStream getInputStream(); 获取套接字的输入流
– public OutputStream getOutputStream() 获取套接字的输出流
– public void close() 关闭套接字
– public void shoutdownOutput() 禁用套接字输出流
– 任何先前写入的数据都将会被发送,最后终止输出流
ServerSocket类
ServerSocket类实现了服务器端套接字,该对象等待通过网络的请求
构造方法
ServerSocket(int port) 使用该构造方法创建ServerSocket创建对象时,就可以将其绑定到一个指定的端口号上面,参数port就是端口号
成员方法
– public Socket accept() 监听并接受链接,返回一个新的Socket对象,用于和用户端实现通信
/*
实现步骤:
1. 创建一个Socket客户端对象,构造方法中绑定服务器的ip地址和端口号
2. 使用Socket对象中的方法getOutputStream获取网络字节输出流对象
3. 使用网络字节输出流对象中的方法write,给服务器发送数据
4. 使用Socket对象中的方法getInputStream()获取网络字节输入流对象
5. 使用网络字节输入流对象调用read方法,读取服务器回写的数据
6. 释放资源(Socket)
java.net.ConnectException: Connection refused: connect
注意事项:
1. 客户端和服务端进行交互的时候,必须使用Socket中提供的网络流,不能使用创建的流对象
2. 当我们创建客户端对象Socket的时候,就会去请求服务器和服务器进行三次握手建立网络连接
这时如果服务器端没有启动,那么程序就会抛出 java.net.ConnectException: Connection refused: connect
如果服务器启动了,那么就可以进行交互。
*/
public class Demo01ClientSocket {
public static void main(String[] args) throws IOException {
// 1. 创建一个Socket客户端对象,构造方法中绑定服务器的ip地址和端口号
Socket socket = new Socket("192.168.53.245", 6666);
// 2. 使用Socket对象中的方法getOutputStream获取网络字节输出流对象
OutputStream os = socket.getOutputStream();
// 3. 使用网络字节输出流对象中的方法write,给服务器发送数据
os.write("我好想你呢111111".getBytes());
// 4. 使用Socket对象中的方法getInputStream()获取网络字节输入流对象
InputStream is = socket.getInputStream();
// 5. 使用网络字节输入流对象调用read方法,读取服务器回写的数据
byte[] bytes = new byte[1024];
int len = is.read(bytes);// 有效字节个数
// 打印下服务器回传的数据
System.out.println(new String(bytes,0,len));
// 6. 释放资源
socket.close();
}
}
/*
服务器端:接收客户端的请求,读取客户端发送的数据,给客户端回写数据
服务器端的实现步骤:
1. 创建ServerSocket服务器端对象和系统指定的端口号
2. 使用ServerSocket对象中的方法accept,获取客户端请求的连接,拿到Socket对象
3. 使用Socket对象中的方法getInputStream(),可以获取网络字节输入流对象
4. 使用网络字节输入流对象中的方法read,读取客户端发送的数据
5. 使用Socket对象中的方法getOutputStream(),获取网络字节输出流对象
6. 使用网络字节输出流对象中的方法write,给客户端回写数据
7. 释放资源(ServerSocket,Socket)
服务器端必须明确到底是哪一个客户端给你发送的请求
可以使用accept方法来获取到客户端对象Socket
通过accept方法来监听接收此套接字的连接。
*/
public class Demo02ServerSocket {
public static void main(String[] args) throws IOException {
//1. 创建ServerSocket服务器端对象和系统指定的端口号
ServerSocket server = new ServerSocket(6666);
//2. 使用ServerSocket对象中的方法accept,获取客户端请求的连接,拿到Socket对象
Socket socket = server.accept();
//3. 使用Socket对象中的方法getInputStream(),可以获取网络字节输入流对象
InputStream is = socket.getInputStream();
//4. 使用网络字节输入流对象中的方法read,读取客户端发送的数据
byte[] bytes = new byte[1024];
int len = is.read(bytes);//
// 打印接收客户端发送的数据
System.out.println(new String(bytes,0,len));
//5. 使用Socket对象中的方法getOutputStream(),获取网络字节输出流对象
OutputStream os = socket.getOutputStream();
//6. 使用网络字节输出流对象中的方法write,给客户端回写数据
os.write("我收到了你的请求消息".getBytes());
//7. 释放资源(ServerSocket,Socket)
socket.close();
server.close();
}
}