TCL协议特点:
- 面向连接,通过三次握手建立连接,通讯完成时要拆除连接,由于面向对象连接,TCP多用于端到端的连接的通讯
- 基于字节流
- 高可靠,TCP采用应答机制,TCP发送的每个报文段都必须得到接受方的应答才 认为TCP报文段传输成功超时重传,发送端在发出一个报文段之后就启动一个报文段之后的一个启动定时器,如果定时时间内没有收到应答就重新发送这个文段
TCP协议组成【暂不深入】
- 协议头
三次握手:【syn标识位,seq number系列号,ACK是一种确认应答,暂未深入了解】
- TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手,确认建立一个连接
- 第一次握手:主机A发送位码为syn=1,随机产生seq number = 200的数据包到服务器,主机B由syn=1知道,A要求建立联机
- 第二次握手:主机B收到请求后确认连接信息,向A发送ack number = (主机A的seq+1),sqn=1,ack=1,随机产生seq number=500的包
- 第三次握手:主机A收到后检查ack number是否正确,即使第一次发送的seq number +1,以及ack是否是1,若正确,主机A会再次发送ack number=(主机B的seq+1),ack=1,主机B接受到后确认seq值与ack=1则建立成功
四次挥手:
- 第一次挥手:客服端A发送一个fin,用来关闭客服端的A到服务器B的数据传送
- 第二次挥手:服务器B收到这个fin,它发回一个ack,确认系列号为为收到的系列号加1和syn一样,一个fin暂用一个系类号
- 第三次挥手:服务器B关闭与客服端A的连接,发送一个FIN给客服端A
- 第四次挥手:客服端A发回ack报文确认,并确定系类号设置为收到系列号加1
Socket基础TCL协议通信Demo【Socket中流是阻塞的关闭与开启需要同步】:
客端端:
package cn.woniux.scoket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 1、创建客服端,必须指定服务器端和端口 2、接受和发送信息给服务端
*
* @author Administrator
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
/*创建客服端,及客服端接受信息的地址及端口*/
Socket client = new Socket("localhost", 8888);
/*将相应资源发送到服务器,客服端输出流,TCL协议许发送字节流,将字节流转换为字符流*/
BufferedWriter bo = new BufferedWriter(
new OutputStreamWriter(client.getOutputStream()));
String str = "客服端第一次请求";
/*接受服务器信息,客户端输入流*/
BufferedReader br = new BufferedReader(
new InputStreamReader(client.getInputStream()));
/*获取输入流内容*/
bo.write(str);
/*使用readLine()读取需要使用newLine()换行*/
bo.newLine();
bo.flush();
String msg = br.readLine();
System.out.println("客服端输出\n" + msg);
}
}
服务端:
package cn.woniux.scoket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 1、创建服务器,指定端口 ServerScoket(port)
* 2、接受客服端的信息
* 3、发送数据和接受数据 接受多个客服端
* 4、基于字节流传输
*
* @author Administrator
*/
public class Server {
public static void main(String[] args) throws IOException {
/* 创建服务器端,指定端口号 */
ServerSocket server = new ServerSocket(8888);
/* 与客服端建立联系 */
Socket socket = server.accept();
/* 接受客服端的信息,服务器输入流,字节流 */
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
/* 将信息发送给客服端,服务器输出流 */
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
String msg = br.readLine();
System.out.println("服务器读取的信息\n" + msg);
bw.write(msg);
/* 使用readLine()读取需要使用newLine()换行 */
bw.newLine();
/*刷出输出流*/
bw.flush();
}
}