三、TCP 通信程序
3.1、TCP 协议概述
TCP 协议是面向连接的通信协议,即在传输数据前先在客户端和服务器端建立逻辑连接,然后再传输数据。它提供了两台计算机之间可靠无差错的数据传输。
他常用于文件上传和下载、邮件发送和接收、远程登录。
3.2、TCP 协议的特点
面向连接的协议。
只能由客户端主动发送数据给服务器端,服务器端接收到数据之后,可以给客户端响应数据。
通过三次握手建立连接,连接成功形成数据传输通道。
通过四次挥手断开连接。
基于 IO 流进行数据传输。
传输数据大小没有限制。
因为面向连接的协议,速度慢,但是是可靠的协议。
3.3、TCP 的三次握手
三次握手:TCP 协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
第一次握手,客户端向服务器端发出连接请求,等待服务器确认。服务器你还活着吗?
第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。我活着啊!!
第三次握手,客户端再次向服务器端发送确认信息,确认连接。我知道了!!
完成三次握手,连接建立后,客户端和服务器就可以开始进行数据传输了。由于这种面向连接的特性,TCP 协议可以保证传输数据的安全,所以应用十分广泛,例如下载文件、浏览网页等。
3.4、TCP 的四次挥手
第一次挥手:客户端请求断开连接。
第二次挥手:服务器发送已经知道要断开,之后把数据发送完。
第三次挥手:服务器发送完数据通知客户端正式断开。
第四次挥手:客户端告知服务器确定要断开并等待 2MSL 之后断开
3.5、TCP 协议相关的类
3.5.1、Socket
一个该类的对象就代表一个客户端程序。
3.5.2、Socket 类构造方法
Socket(String host, int port)
:根据 ip 地址字符串和端口号创建客户端 Socket 对象。
只要执行该方法,就会立即连接指定的服务器程序,如果连接不成功,则会抛出异常。如果连接成功,则表示三次握手通过。
3.5.3、Socket 类常用方法
OutputStream getOutputStream()
:获得字节输出流对象。
InputStream getInputStream()
:获得字节输入流对象。
3.5.4、ServerSocket
一个该类的对象就代表一个服务器端程序。
3.6、TCP 通信案例
3.6.1、客户端向服务器发送数据
/*
TCP客户端代码实现步骤
* 创建客户端Socket对象并指定服务器地址和端口号
* 调用Socket对象的getOutputStream方法获得字节输出流对象
* 调用字节输出流对象的write方法往服务器端输出数据
* 调用Socket对象的getInputStream方法获得字节输入流对象
* 调用字节输入流对象的read方法读取服务器端返回的数据
* 关闭Socket对象断开连接。
*/
// TCP客户端代码实现
public class TCPClient {
public static void main(String[] args) throws Exception{
// 要发送的内容
String content = "你好TCP服务器端,约吗";
// 创建Socket对象
Socket socket = new Socket("192.168.73.99",9999);
// System.out.println(socket);
// 获得字节输出流对象
OutputStream out = socket.getOutputStream();
// 输出数据到服务器端
out.write(content.getBytes());
// 获得字节输入流对象
InputStream in = socket.getInputStream();
// 创建字节数组:用来存储读取到服务器端数据
byte[] buf = new byte[1024];
// 读取服务器端返回的数据
int len = in.read(buf);
System.out.println("len = " + len);
System.out.println("服务器端返回的内容 = " + new String(buf,0,len));
// 关闭socket对象
socket.close();
}
}
复制代码
3.6.2、服务器向客户端回写数据
/**
TCP服务器端代码实现
ServerSocket类构造方法
* ServerSocket(int port) 根据指定的端口号开启服务器。
ServerSocket类常用方法
* Socket accept() 等待客户端连接并获得与客户端关联的Socket对象
TCP服务器端代码实现步骤
* 创建ServerSocket对象并指定端口号(相当于开启了一个服务器)
* 调用ServerSocket对象的accept方法等待客端户连接并获得对应Socket对象
* 调用Socket对象的getInputStream方法获得字节输入流对象
* 调用字节输入流对象的read方法读取客户端发送的数据
* 调用Socket对象的getOutputStream方法获得字节输出流对象
* 调用字节输出流对象的write方法往客户端输出数据
* 关闭Socket和ServerSocket对象
*/
public class TCPServer {
public static void main(String[] args)throws Exception{
// 创建服务器ocket对象
ServerSocket serverSocket = new ServerSocket(9999);
// 等待客户端连接并获得与客户端关联的Socket对象
Socket socket = serverSocket.accept();
// 获得字节输入流对象
InputStream in = socket.getInputStream();
// 创建字节数组:用来存储读取到客户端发送的数据
byte[] buf = new byte[1024];
// 读取客户端发送过来的数据
int len = in.read(buf);
System.out.println("len = " + len);
System.out.println("客户端发送的数据 = " + new String(buf,0,len));
// 获得字节输出流对象
OutputStream out = socket.getOutputStream();
// 往客户端输出数据
out.write("约你妹".getBytes());
// 关闭socket
socket.close();
// 关闭服务器(在实际开发中,服务器一般不会关闭)
serverSocket.close();
}
}
复制代码
stem.out.println("len = " + len);System.out.println("客户端发送的数据 = " + new String(buf,0,len));
// 获得字节输出流对象
OutputStream out = socket.getOutputStream();
// 往客户端输出数据
out.write("约你妹".getBytes());
// 关闭socket
socket.close();
// 关闭服务器(在实际开发中,服务器一般不会关闭)
serverSocket.close();
}
复制代码
}
评论