1 TCP 三次握手四次挥手
1.1 三次握手
1.2 四次挥手
2 Java 实现 TCP 客户端与 TCP 服务端连接
2.1 客户端
首先需要明确目标地址信息,然后创建连接,接着通过 IO 发送数据,最后关闭连接。
/**
* TCP 客户端
*/
public class TCPClientTest {
public static void main(String[] args) {
InetAddress serverAddress = null;
Socket socket = null;
OutputStream os = null;
try {
// 获取服务端地址
serverAddress = InetAddress.getByName("127.0.0.1");
int port = 8888;
// 创建与服务端的连接
socket = new Socket(serverAddress, port);
// 通过 IO 流发送消息
os = socket.getOutputStream();
os.write("Hello, I'm PkyShare".getBytes());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
// 关闭流,逐级关闭
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.2 TCP 服务端
首先是定义自己的地址信息,然后等待客户端连接,接着读取客户端的消息,最后关闭连接。
/**
* TCP 服务端
*/
public class TCPServerTest {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
// 开放服务端端口
serverSocket = new ServerSocket(8888);
// 阻塞式监听,一直等待客户端连接
socket = serverSocket.accept();
// 通过 IO 流接收客户端数据
is = socket.getInputStream();
// 管道流转为 String(用管道流避免中文乱码)
baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1) {
baos.write(bytes, 0, len);
}
System.out.println(baos.toString());
}
catch (IOException e) {
e.printStackTrace();
}
finally {
// 逐级关闭流
if(baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.3 测试结果
先启动服务端,然后再启动客户端。当客户端启动完成后,服务端就会接受到信息。
服务端控制台输出:
Hello, I'm PkyShare
必须先启动服务端才能发送消息,也就必须先建立连接。如果先启动客户端,则会报连接不上的异常。
3 文件传输
3.1 客户端
主要是用文件流进行传输。
/**
* TCP 客户端
*/
public class TCPClientTest {
public static void main(String[] args) {
InetAddress serverAddress = null;
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
try {
// 获取服务端地址
serverAddress = InetAddress.getByName("127.0.0.1");
int port = 8888;
// 创建与服务端的连接
socket = new Socket(serverAddress, port);
// 通过 IO 流发送消息
os = socket.getOutputStream();
// 文件传输
fis = new FileInputStream(new File("C:\\Users\\Administrator.DESKTOP-1M3KMF6\\Desktop\\pky.jpg"));
byte[] bytes = new byte[1024];
int len;
while ((len = fis.read()) != -1) {
os.write(bytes, 0 , len);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
// 关闭流,逐级关闭
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.2 服务端
/**
* TCP 服务端
*/
public class TCPServerTest {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
try {
// 创建服务端地址
serverSocket = new ServerSocket(8888);
// 等待客户端连接
socket = serverSocket.accept();
// 通过 IO 流接收客户端数据
is = socket.getInputStream();
// 读取文件
fos = new FileOutputStream(new File("pkyServer.jpg"));
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
// 逐级关闭流
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}