java从零开发TCPIP协议:实现TCP数据的收发机制

本节我们在上一节基础上进一步完成TCP协议的收发机制。上一节我们已经实现了向服务器方发送一个字符,本节我们要实现连续发送多个字符,并且能正常接收数据功能,完成了这些功能后,我们就可以基于此去开发其他构建在TCP之上的其他协议。

为了保证数据能正确的连续收发,本节的设计思路是使用一个队列将发送的数据存储起来,然后将数据包发送,只有等待收到对方回发的ack后,我们才将数据从队列中删除,如果数据包一直没有收到ack回应,我们就启动一个timer,自动将队列中的数据包进行发送,如果发送给定次数后还没有成功,那么就通知数据发送层发送失败,接下来我们看看相应代码设计。

class SendPacketWrapper {
	//将发送的数据包封装起来存储在队列中
	private byte[] packet_to_send;
	private int seq_num;
	private int ack_num;
	private int send_count = 0;

	public SendPacketWrapper(byte[] packet, int seq_num) {
		this.packet_to_send = packet;
		this.seq_num = seq_num;
		this.ack_num = seq_num + packet.length;
	}
	
	public byte[] get_packet() {
		return this.packet_to_send;
	}
	public int get_seq_num() {
		return this.seq_num;
	}
	public int get_ack_num() {
		return this.ack_num;
	}
	public void increase_send_count() {
		this.send_count++;
	}
	public int get_send_count() {
		return this.send_count;
	}

}

class  SendPacketTask extends TimerTask {
	private TCPThreeHandShakes  task_handler;
	public SendPacketTask(TCPThreeHandShakes  handler) {
		this.task_handler = handler;
	}
	@Override
	public void run() {
		this.task_handler.sendPacketInList();
	}
}

第一个类用于负责把发送的数据封装起来,他记录了数据的缓冲区,以及发送时对应的seq号,这样当数据包需要重发时就可以再次使用这个数值进行发送,同时也记录了应对的ack号,这样当对方返回ack值时,我们才能检验该数据包是否已经被对方接收。

接下来我们在类TCPThreeHandShakes中添加相应变量和代码:

public class TCPThreeHandShakes extends Application{
    。。。。
    	private int  tcp_state = CONNECTION_IDLE;
	private static int PACKET_SEND_TIMES = 3; //连续发生3次不成功则失败
	private  Timer send_timer = new Timer(); //定时将发送队列中的数据包进行发送
	private int packet_resend_time = 2000; //每过一秒就发送队列中存储的数据包
	private SendPacketTask resend_packet_task = null;
	//每次发送数据包时先将它存储在队列中,发送出去收到ack后再将它从队列中去除
	private ArrayList<SendPacketWrapper> send_packet_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值