? ? ? ? 非常重要的知识点:三次握手发生在内核态,操作系统内核去,执行握手操作。Socket连接成功后,已经完成了三次握手。以下演示的程序,只是模拟演示一下。
????????TcpClient客户端代码如下:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
/**
* 〈一句话功能简述〉<br>
* 〈使用Socket演示Tcp三次握手〉
* <p>
*
* @author hanxiaozhang
* @create 2023/5/31
* @since 1.0.0
*/
public class TcpClient {
/**
* 服务器监听的端口号
*/
private static final int PORT = 56002;
private static final int TIMEOUT = 15000;
public static void main(String[] args) {
Socket client = null;
try {
// 调用无参构造方法
client = new Socket();
// 构造服务器地址结构
SocketAddress serverAddr = new InetSocketAddress("127.0.0.1", PORT);
// 连接服务器,超时时间是 15 毫秒
client.connect(serverAddr, TIMEOUT);
System.out.println("Client start: " + client.getLocalSocketAddress().toString());
// 向服务器发送数据 client SYN
String req = "SYN seq 543067661";
TcpUtil.sendMsg(client, req);
System.out.println("Client Send to server: " + req);
// 接收服务器的数据 server SYN + ACK
String msg = TcpUtil.receiveMsg(client);
System.out.println("Client Recv from server: " + msg);
// 向服务器发送数据 client ACK
req = "ACK ack 3824468341";
TcpUtil.sendMsg(client, req);
System.out.println("Client Send to server: " + req);
// ---- 通信 ----
req = "Hello,Nice to meet you";
TcpUtil.sendMsg(client, req);
System.out.println("Client Send to server: " + req);
msg = TcpUtil.receiveMsg(client);
System.out.println("Client Recv from server: " + msg);
req = "Bye";
TcpUtil.sendMsg(client, req);
System.out.println("Client Send to server: " + req);
msg = TcpUtil.receiveMsg(client);
System.out.println("Client Recv from server: " + msg);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (client != null) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
?????????TcpServer服务端代码如下:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeUnit;
/**
* 〈一句话功能简述〉<br>
* 〈使用Socket演示Tcp三次握手〉
*
* @author hanxiaozhang
* @create 2023/5/31
* @since 1.0.0
*/
public class TcpServer {
private static final int PORT = 56002;
public static void main(String[] args) {
ServerSocket ss = null;
try {
// 创建一个服务器 Socket
ss = new ServerSocket(PORT);
// 监听新连接请求,阻塞获取
Socket conn = ss.accept();
System.out.println("Accept a new connection: " + conn.getRemoteSocketAddress().toString());
// 读取客户端数据 client ACK
String msg = TcpUtil.receiveMsg(conn);
System.out.println("Server Recv from client: " + msg);
// 向客户端发送数据 server ACK + SYN
String req = "SYN seq 3824468340 ACK ack 543067662";
TcpUtil.sendMsg(conn, req);
System.out.println("Server Send to client: " + req);
// 读取客户端数据 client ACK
msg = TcpUtil.receiveMsg(conn);
System.out.println("Server Recv from client: " + msg);
// ---- 通信 ----
msg = TcpUtil.receiveMsg(conn);
System.out.println("Server Recv from client: " + msg);
req = "Hello,Nice to meet you too";
TcpUtil.sendMsg(conn, req);
System.out.println("Server Send to client: " + req);
// ---- 关闭链接 ----
req = "see you";
TcpUtil.sendMsg(conn, req);
System.out.println("Server Send to client: " + req);
TimeUnit.SECONDS.sleep(1);
conn.close();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Server exit!");
}
}
?????????TcpUtil工具类
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
/**
* 〈一句话功能简述〉<br>
* 〈〉
*
* @author hanxiaozhang
* @create 2023/6/9
* @since 1.0.0
*/
public class TcpUtil {
/**
* 接受消息
*
* @param socket
* @return
* @throws IOException
*/
public static String receiveMsg(Socket socket) throws IOException {
StringBuilder inMessage = new StringBuilder();
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
while (true) {
int c = in.read();
if (c == -1 || c == '\n') {
break;
}
inMessage.append((char) c);
}
return inMessage.toString();
}
/**
* 发送消息
*
* @param socket
* @param req
* @throws IOException
*/
public static void sendMsg(Socket socket, String req) throws IOException {
req = req + "\n";
OutputStream out = new BufferedOutputStream(socket.getOutputStream());
out.write(req.getBytes());
// 不能忘记 flush 方法的调用
out.flush();
}
}