TCP编程
本篇文章是在Java环境中使用TCP对数据进行收发的教程。
TCP编程的作用
TCP是面向连接的可靠的协议,使用TCP编程可以保证数据的可靠传输,避免数据丢失和损坏,同时还能提高网络的利用率和传输效率,适合于对数据传输质量有较高要求的应用场景。
TCP的优点
- 可靠性:TCP协议使用确认应答机制和重传机制来确保数据的可靠传输,保证数据的完整性和顺序性。
- 流量控制:TCP协议提供了流量控制机制,通过动态调整发送窗口的大小来控制数据传输的速度,避免网络拥塞,提高网络的利用率。
- 拥塞控制:TCP协议还提供了拥塞控制机制,通过动态调整发送速率和接收速率来控制网络拥塞,避免网络崩溃。
- 传输效率高:TCP协议采用了分段和缓存等技术,能够在网络状况不佳的情况下保持高效的传输速度,提高传输效率。
- 应用广泛:TCP协议被广泛应用于Web浏览器、电子邮件、文件传输等应用中,成为互联网通信的基础协议之一。
为什么使用TCP
本来网络通过IP就能找到对应的主机,但是一个主机上有很多端口,不同端口又对应不同的应用程序。
因此,仅仅是使用IP是不够的,还要使用TCP去获取端口
即使用TCP/IP, Java封装了Socket
与ServerSocket
来实现Java中的TCP编程
在Java中的使用步骤
- 创建
ServerSocket
对象:通过ServerSocket
类的构造函数创建一个ServerSocket对象,指定服务器监听的端口号。 - 监听客户端连接:通过
ServerSocket
对象的accept()
方法监听客户端的连接请求,并返回一个新的Socket
对象,表示与客户端建立的连接。 - 获取输入输出流:通过
Socket
对象的getInputStream()
和getOutputStream()
方法获取输入输出流,用于进行数据的读取和写入。 - 数据传输:使用输入输出流进行数据的读取和写入,可以使用Java的IO类库提供的
Reader
和Writer
等类进行数据的读写操作。(这两个类主要是处理字符串) - 关闭连接:在完成数据传输后,通过
Socket
对象的close()
方法关闭连接,释放资源。
服务端代码
我们是将代码分为了服务端与客户端, 服务端负责监听指定端口并等待连接。
public class SocketServer {
public static void main(String[] args) {
try {
// 监听 8888 端口
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端启动, 等待连接");
// 阻塞代码,直到有链接,没有连接会被置为休眠线程,所以不会占用很大内存
Socket socket = serverSocket.accept();
System.out.println("客户端连接成功, 客户端地址: " + socket.getInetAddress());
// 获取客户端的输入
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String message = bufferedReader.readLine();
System.out.println("客户端发来的消息: " + message);
// 服务端可以通过Socket对象的getOutputStream()方法获取与客户端建立的连接的输出流,用于向客户端发送数据。
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.write("你好,客户端, 我是服务端!");
printWriter.flush();
socket.shutdownOutput();
// 关闭连接
bufferedReader.close();
inputStream.close();
printWriter.close();
outputStream.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码
客户端首先建立与服务器的连接, 然后进行输出,调用socket
对象的getOutputStream()
方法从而向服务端发送数据。
public class SocketClient {
public static void main(String[] args) {
try {
// 去连接服务端
Socket socket = new Socket("localhost", 8888);
// 向服务端发送消息
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.write("你好, 服务端,我是客户端!");
printWriter.flush();
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String message = null;
while ((message = bufferedReader.readLine()) != null) {
System.out.println("服务器回应: " + message);
}
bufferedReader.close();
inputStream.close();
printWriter.close();
outputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}