TCP Socket执行流程
-
服务器首先运行,等待连接建立
创建欢迎socket
和本地端口号绑定(客户端访问的指定端口号)
在欢迎socket上阻塞的等待接受用户的连接 -
客户端主动和服务器建立连接
创建客户端本地套接字(隐式捆绑到本地port)
指定服务器的IP地址和端口号,和服务器进程连接 -
服务器收到来自客户端的请求,进行处理
服务器接收来自客户端的请求,解除阻塞式等待,返回一个新的socket(和欢迎socket不一样),与客户端通信
允许服务器与多个客户端通信
使用客户端IP+端口来区分不同的客户端 -
连接API调用有效时,客户端与服务器建立了TCP连接
socket server
package sockettcp;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Objects;
/**
* tcp socket server
*
* @author zhao.hualuo
* Create at 2022/2/25
*/
public class SocketServer {
public static void main(String[] args) {
try {
//初始化服务器端socket(welcome socket),是一个守护进程,需要提前设置好端口号
ServerSocket serverSocket = new ServerSocket(8088);
//不停的轮询,接收客户端请求
while (true) {
//接收客户端请求,若无请求,则程序卡在此处等待连接
Socket socket = serverSocket.accept();
//获取并打印客户端socket请求地址
System.out.println("建立socket连接,当前连接的客户端IP是:" + socket.getInetAddress().getHostAddress() + ",端口号:" + socket.getPort());
while (Objects.nonNull(socket)) {
//获取客户端传输的内容
DataInputStream dis = new DataInputStream(socket.getInputStream());
String info = dis.readUTF();
System.out.println("客户端:" + info);
//向客户端发送响应内容
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
String out = "已收到消息-" + info;
System.out.println(out);
dos.writeUTF(out);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
socket client
package sockettcp;
import java.io.*;
import java.net.Socket;
import java.util.Objects;
import java.util.Scanner;
/**
* tcp socket client
*
* @author zhao.hualuo
* Create at 2022/2/25
*/
public class SocketClient {
public static void main(String[] args) {
Socket socket = null;
DataOutputStream dos = null;
DataInputStream dis = null;
try {
//初始化客户端socket,需指定服务器端socket的IP地址和端口号
//和服务器端建立socket请求
socket = new Socket("127.0.0.1",8088);
//接受来自服务器端的消息
dis = new DataInputStream(socket.getInputStream());
//向服务器端发送消息
dos = new DataOutputStream(socket.getOutputStream());
//多次通信
Scanner sc = new Scanner(System.in);
while (true) {
//输入一行通信内容
String line = sc.nextLine();
dos.writeUTF(line);
//接收服务器端的回应
String answer = dis.readUTF();
System.out.println("服务器:" + answer);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close(dos);
close(dis);
close(socket);
}
}
public static void close(Closeable io){
if(Objects.nonNull(io)){
try {
io.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
测试功能
-
先启动服务器
-
启动客户端
客户端启动后,已经向服务器请求建立连接
-
客户端输入内容
客户端输入内容后,服务器端收到请求,并做出响应。
-
客户端再次输入内容
tcp连接建立后可以一直通信,不用每次都建立连接