stm32改php,TCP 协议在 STM32 上的移植

void tcp_send_packet (

BYTE *rxtx_buffer, //发送缓冲区

WORD_BYTES dest_port, // 目标端口号

WORD_BYTES src_port, // 源端口号

BYTE flags, // TCP标志 FIN SYN ACK

BYTE max_segment_size, // 初始化序号 接收SYN时使用

BYTE clear_seqack, // 设置确认号为0 发送SYN时使用

WORD next_ack_num, // 在上一个数据包序号的基础上累加

WORD dlength, // 负载长度

BYTE *dest_mac, // 目标MAC地址

BYTE *dest_ip ) // 目标IP地址

{

BYTE i, tseq;

WORD_BYTES ck;

// 生成以太网报文头

eth_generate_header ( rxtx_buffer, (WORD_BYTES){ETH_TYPE_IP_V}, dest_mac );

// 计算数据包 确认号 next_ack_num为累加值

// 1.确认号因等于上一个数据包的序号加上数据包长度

// 2.序号等于上一个数据包的确认号

// 3.FIN和SYN各占一个序号

// 4.确认号和序号使用大端模式,即高地址存放低位数据

// 5.确认号修改发生在三种情况,接收到SYN,接收到FIN,接收到负载数据

if ( next_ack_num )

{

for( i = 4 ; i > 0; i-- )

{

// 取出上一个数据包的序号,累加next_ack_num

next_ack_num = rxtx_buffer [ TCP_SEQ_P + i - 1] + next_ack_num;

// 取出上一个数据包的确认号

tseq = rxtx_buffer [ TCP_SEQACK_P + i - 1];

// 复制本次数据包的确认号,即上个数据包的序号+next_ack_num

rxtx_buffer [ TCP_SEQACK_P + i - 1] = 0xff & next_ack_num;

// 复制上一个数据包的确认号于本数据包的序号

rxtx_buffer[ TCP_SEQ_P + i - 1 ] = tseq;

next_ack_num >>= 8;

}

}

// 初始化序号

// 设置最大分片

// 第一次发送或接收时使用

if ( max_segment_size )

{

// 初始化序号

rxtx_buffer[ TCP_SEQ_P + 0 ] = 0;

rxtx_buffer[ TCP_SEQ_P + 1 ] = 0;

rxtx_buffer[ TCP_SEQ_P + 2 ] = seqnum;

rxtx_buffer[ TCP_SEQ_P + 3 ] = 0;

seqnum += 2;

// 初始化 报文段最大长度

rxtx_buffer[ TCP_OPTIONS_P + 0 ] = 2; // 最大报文长度

rxtx_buffer[ TCP_OPTIONS_P + 1 ] = 4; // TCP选项长度 TCP选项格式2

rxtx_buffer[ TCP_OPTIONS_P + 2 ] = HIGH(1408); //

rxtx_buffer[ TCP_OPTIONS_P + 3 ] = LOW(1408); //

// 数据偏移,占用高4位,且计算长度为双字

rxtx_buffer[ TCP_HEADER_LEN_P ] = 0x60;

dlength += 4;

}

else

{

// 没有TCP选项时长度为5个双字

rxtx_buffer[ TCP_HEADER_LEN_P ] = 0x50;

}

// generate ip header and checksum

ip_generate_header ( rxtx_buffer, (WORD_BYTES){(IP_HEADER_LEN + TCP_HEADER_LEN + dlength)}, IP_PROTO_TCP_V, dest_ip );

// 清除序号,一般使用于发送SYN时

if ( clear_seqack )

{

rxtx_buffer[ TCP_SEQACK_P + 0 ] = 0;

rxtx_buffer[ TCP_SEQACK_P + 1 ] = 0;

rxtx_buffer[ TCP_SEQACK_P + 2 ] = 0;

rxtx_buffer[ TCP_SEQACK_P + 3 ] = 0;

}

// 设置TCP标志

rxtx_buffer [ TCP_FLAGS_P ] = flags;

// 设置目标端口号

rxtx_buffer [ TCP_DST_PORT_H_P ] = dest_port.byte.high;

rxtx_buffer [ TCP_DST_PORT_L_P ] = dest_port.byte.low;

// 设置源端口号

rxtx_buffer [ TCP_SRC_PORT_H_P ] = src_port.byte.high;

rxtx_buffer [ TCP_SRC_PORT_L_P ] = src_port.byte.low;

// 设置TCP窗口大小

rxtx_buffer [ TCP_WINDOWSIZE_H_P ] = HIGH((MAX_RX_BUFFER-IP_HEADER_LEN-ETH_HEADER_LEN));

rxtx_buffer [ TCP_WINDOWSIZE_L_P ] = LOW((MAX_RX_BUFFER-IP_HEADER_LEN-ETH_HEADER_LEN));

// 紧急指针

rxtx_buffer[ TCP_URGENT_PTR_H_P ] = 0;

rxtx_buffer[ TCP_URGENT_PTR_L_P ] = 0;

// 计算校验和

rxtx_buffer[ TCP_CHECKSUM_H_P ] = 0;

rxtx_buffer[ TCP_CHECKSUM_L_P ] = 0;

ck.word = software_checksum( &rxtx_buffer[IP_SRC_IP_P], TCP_HEADER_LEN+dlength+8, IP_PROTO_TCP_V + TCP_HEADER_LEN + dlength );

rxtx_buffer[ TCP_CHECKSUM_H_P ] = ck.byte.high;

rxtx_buffer[ TCP_CHECKSUM_L_P ] = ck.byte.low;

// 通过enc28j60发送数据

enc28j60_packet_send ( rxtx_buffer, ETH_HEADER_LEN+IP_HEADER_LEN+TCP_HEADER_LEN+dlength );

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值